diff --git a/.gitignore b/.gitignore index 0111e02..a5a1e41 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,9 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties .mvn/wrapper/maven-wrapper.jar + +# IntelliJ IDEA files +*.iml +.idea/ +*.iws +*.ipr diff --git a/README.md b/README.md index 9721f79..625ed2e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ -# oss-maven-template +# SNMP Java Client -![GitHub release (with filter)](https://img.shields.io/github/v/release/sentrysoftware/oss-maven-template) -![Build](https://img.shields.io/github/actions/workflow/status/sentrysoftware/oss-maven-template/deploy.yml) -![GitHub top language](https://img.shields.io/github/languages/top/sentrysoftware/oss-maven-template) -![License](https://img.shields.io/github/license/sentrysoftware/oss-maven-template) +![GitHub release (with filter)](https://img.shields.io/github/v/release/sentrysoftware/snmp) +![Build](https://img.shields.io/github/actions/workflow/status/sentrysoftware/snmp/deploy.yml) +![GitHub top language](https://img.shields.io/github/languages/top/sentrysoftware/snmp) +![License](https://img.shields.io/github/license/sentrysoftware/snmp) -Repository template for all Sentry open-source Java projects, published on Maven Central. +This project is a fork of the excellent [Westhawk's SNMP Library for Java](https://snmp.westhawk.co.uk/) ([see also](https://code.google.com/archive/p/snmp123)). + +The SNMP Java client is designed to interact with remote hosts implementing SNMP v1, v2c, or v3 and allows to execute SNMP requests, including `Get` and `GetNext` requests as well as `Walk` and `Table` functionalities that represent an enhancements over traditional SNMP `Get` and `GetNext` methods. + +See [Project Documentation](https://sentrysoftware.github.io/snmp/) and the [Javadoc](https://sentrysoftware.github.io/snmp/apidocs/) for more information on how to use this library in your code. ## Build instructions @@ -31,8 +35,7 @@ But it is strongly recommended to only use [GitHub Actions "Release to Maven Cen ## License -License is Apache-2. Each source file must include the Apache-2 header (build will fail otherwise). -To update source files with the proper header, simply execute the below command: +License is GNU General Lesser Public License (LGPL) version 3.0. Each source file includes the LGPL-3 header (build will fail otherwise). To update source files with the proper header, simply execute the below command: ```bash mvn license:update-file-header diff --git a/pom.xml b/pom.xml index 6494976..827f02c 100644 --- a/pom.xml +++ b/pom.xml @@ -2,18 +2,18 @@ 4.0.0 org.sentrysoftware - MYARTIFACT - MY PROJECT - 0.1.00-SNAPSHOT - SOME DESCRIPTION - jar + snmp + SNMP Java Client + 1.0.00-SNAPSHOT + SNMP Client Library for Java + jar Sentry Software https://sentrysoftware.com - https://github.com/sentrysoftware/MYREPO + https://sentrysoftware.github.io/snmp 2023 @@ -29,37 +29,56 @@ - Apache-2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt + LGPL-3.0 + https://www.gnu.org/licenses/lgpl+gpl-3.0.txt repo GitHub - https://github.com/sentrysoftware/MYREPO/issues/ + https://github.com/sentrysoftware/snmp/issues/ - scm:git:https://github.com/sentrysoftware/MYREPO.git - https://github.com/sentrysoftware/MYREPO + scm:git:https://github.com/sentrysoftware/snmp.git + https://sentrysoftware.github.io/snmp HEAD - MY NAME (@MY_ID) - MYNAME@sentrysoftware.com + Bertrand Martin (@bertysentry) + bertrand@sentrysoftware.com - Project founder + maintainer + + + + Nassim Boutekedjiret (@NassimBtk) + nassim@sentrysoftware.com + + maintainer + + + + Kawtar Bakour (@KawtarBK9) + kawtar@sentrysoftware.com + + maintainer + + + + Elyes Cherfa (@CherfaElyes) + elyes@sentrysoftware.com + + maintainer - 11 - 11 11 @@ -153,7 +172,7 @@ license-maven-plugin 2.3.0 - apache_v2 + lgpl_v3 Sentry Software Copyright %1$s %2$s @@ -183,6 +202,9 @@ maven-javadoc-plugin + + all,-missing + attach-javadocs diff --git a/src/main/java/org/bouncycastle/crypto/BlockCipher.java b/src/main/java/org/bouncycastle/crypto/BlockCipher.java new file mode 100644 index 0000000..4aec920 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/BlockCipher.java @@ -0,0 +1,78 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * Block cipher engines are expected to conform to this interface. + */ +public interface BlockCipher +{ + /** + * Initialise the cipher. + * + * @param forEncryption if true the cipher is initialised for + * encryption, if false for decryption. + * @param params the key and other data required by the cipher. + * @exception IllegalArgumentException if the params argument is + * inappropriate. + */ + public void init(boolean forEncryption, CipherParameters params) + throws IllegalArgumentException; + + /** + * Return the name of the algorithm the cipher implements. + * + * @return the name of the algorithm the cipher implements. + */ + public String getAlgorithmName(); + + /** + * Return the block size for this cipher (in bytes). + * + * @return the block size for this cipher in bytes. + */ + public int getBlockSize(); + + /** + * Process one block of input from the array in and write it to + * the out array. + * + * @param in the array containing the input data. + * @param inOff offset into the in array the data starts at. + * @param out the array the output data will be copied into. + * @param outOff the offset into the out array the output will start at. + * @exception DataLengthException if there isn't enough data in in, or + * space in out. + * @exception IllegalStateException if the cipher isn't initialised. + * @return the number of bytes processed and produced. + */ + public int processBlock(byte[] in, int inOff, byte[] out, int outOff) + throws DataLengthException, IllegalStateException; + + /** + * Reset the cipher. After resetting the cipher is in the same state + * as it was after the last init (if there was one). + */ + public void reset(); +} diff --git a/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java b/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java new file mode 100644 index 0000000..4c887ed --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/CipherKeyGenerator.java @@ -0,0 +1,60 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.security.SecureRandom; + +/** + * The base class for symmetric, or secret, cipher key generators. + */ +public class CipherKeyGenerator +{ + protected SecureRandom random; + protected int strength; + + /** + * initialise the key generator. + * + * @param param the parameters to be used for key generation + */ + public void init( + KeyGenerationParameters param) + { + this.random = param.getRandom(); + this.strength = (param.getStrength() + 7) / 8; + } + + /** + * generate a secret key. + * + * @return a byte array containing the key value. + */ + public byte[] generateKey() + { + byte[] key = new byte[strength]; + + random.nextBytes(key); + + return key; + } +} diff --git a/src/main/java/org/bouncycastle/crypto/CipherParameters.java b/src/main/java/org/bouncycastle/crypto/CipherParameters.java new file mode 100644 index 0000000..84a83ca --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/CipherParameters.java @@ -0,0 +1,30 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * all parameter classes implement this. + */ +public interface CipherParameters +{ +} diff --git a/src/main/java/org/bouncycastle/crypto/DataLengthException.java b/src/main/java/org/bouncycastle/crypto/DataLengthException.java new file mode 100644 index 0000000..2241c49 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/DataLengthException.java @@ -0,0 +1,51 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * this exception is thrown if a buffer that is meant to have output + * copied into it turns out to be too short, or if we've been given + * insufficient input. In general this exception will get thrown rather + * than an ArrayOutOfBounds exception. + */ +public class DataLengthException + extends RuntimeCryptoException +{ + /** + * base constructor. + */ + public DataLengthException() + { + } + + /** + * create a DataLengthException with the given message. + * + * @param message the message to be carried with the exception. + */ + public DataLengthException( + String message) + { + super(message); + } +} diff --git a/src/main/java/org/bouncycastle/crypto/Digest.java b/src/main/java/org/bouncycastle/crypto/Digest.java new file mode 100644 index 0000000..5aeb249 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/Digest.java @@ -0,0 +1,73 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * interface that a message digest conforms to. + */ +public interface Digest +{ + /** + * return the algorithm name + * + * @return the algorithm name + */ + public String getAlgorithmName(); + + /** + * return the size, in bytes, of the digest produced by this message digest. + * + * @return the size, in bytes, of the digest produced by this message digest. + */ + public int getDigestSize(); + + /** + * update the message digest with a single byte. + * + * @param in the input byte to be entered. + */ + public void update(byte in); + + /** + * update the message digest with a block of bytes. + * + * @param in the byte array containing the data. + * @param inOff the offset into the byte array where the data starts. + * @param len the length of the data. + */ + public void update(byte[] in, int inOff, int len); + + /** + * close the digest, producing the final digest value. The doFinal + * call leaves the digest reset. + * + * @param out the array the digest is to be copied into. + * @param outOff the offset into the out array the digest is to start at. + */ + public int doFinal(byte[] out, int outOff); + + /** + * reset the digest back to it's initial state. + */ + public void reset(); +} diff --git a/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java b/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java new file mode 100644 index 0000000..73441ac --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/KeyGenerationParameters.java @@ -0,0 +1,70 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.security.SecureRandom; + +/** + * The base class for parameters to key generators. + */ +public class KeyGenerationParameters +{ + private SecureRandom random; + private int strength; + + /** + * initialise the generator with a source of randomness + * and a strength (in bits). + * + * @param random the random byte source. + * @param strength the size, in bits, of the keys we want to produce. + */ + public KeyGenerationParameters( + SecureRandom random, + int strength) + { + this.random = random; + this.strength = strength; + } + + /** + * return the random source associated with this + * generator. + * + * @return the generators random source. + */ + public SecureRandom getRandom() + { + return random; + } + + /** + * return the bit strength for keys produced by this generator, + * + * @return the strength of the keys this generator produces (in bits). + */ + public int getStrength() + { + return strength; + } +} diff --git a/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java b/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java new file mode 100644 index 0000000..14efaf1 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java @@ -0,0 +1,48 @@ +package org.bouncycastle.crypto; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * the foundation class for the exceptions thrown by the crypto packages. + */ +public class RuntimeCryptoException + extends RuntimeException +{ + /** + * base constructor. + */ + public RuntimeCryptoException() + { + } + + /** + * create a RuntimeCryptoException with the given message. + * + * @param message the message to be carried with the exception. + */ + public RuntimeCryptoException( + String message) + { + super(message); + } +} diff --git a/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java b/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java new file mode 100644 index 0000000..75115c0 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java @@ -0,0 +1,150 @@ +package org.bouncycastle.crypto.digests; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import org.bouncycastle.crypto.Digest; + +/** + * base implementation of MD4 family style digest as outlined in + * "Handbook of Applied Cryptography", pages 344 - 347. + */ +public abstract class GeneralDigest + implements Digest +{ + private byte[] xBuf; + private int xBufOff; + + private long byteCount; + + /** + * Standard constructor + */ + protected GeneralDigest() + { + xBuf = new byte[4]; + xBufOff = 0; + } + + /** + * Copy constructor. We are using copy constructors in place + * of the Object.clone() interface as this interface is not + * supported by J2ME. + */ + protected GeneralDigest(GeneralDigest t) + { + xBuf = new byte[t.xBuf.length]; + System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); + + xBufOff = t.xBufOff; + byteCount = t.byteCount; + } + + public void update( + byte in) + { + xBuf[xBufOff++] = in; + + if (xBufOff == xBuf.length) + { + processWord(xBuf, 0); + xBufOff = 0; + } + + byteCount++; + } + + public void update( + byte[] in, + int inOff, + int len) + { + // + // fill the current word + // + while ((xBufOff != 0) && (len > 0)) + { + update(in[inOff]); + + inOff++; + len--; + } + + // + // process whole words. + // + while (len > xBuf.length) + { + processWord(in, inOff); + + inOff += xBuf.length; + len -= xBuf.length; + byteCount += xBuf.length; + } + + // + // load in the remainder. + // + while (len > 0) + { + update(in[inOff]); + + inOff++; + len--; + } + } + + public void finish() + { + long bitLength = (byteCount << 3); + + // + // add the pad bytes. + // + update((byte)128); + + while (xBufOff != 0) + { + update((byte)0); + } + + processLength(bitLength); + + processBlock(); + } + + public void reset() + { + byteCount = 0; + + xBufOff = 0; + for ( int i = 0; i < xBuf.length; i++ ) { + xBuf[i] = 0; + } + } + + protected abstract void processWord(byte[] in, int inOff); + + protected abstract void processLength(long bitLength); + + protected abstract void processBlock(); +} diff --git a/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java b/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java new file mode 100644 index 0000000..3767f20 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java @@ -0,0 +1,324 @@ +package org.bouncycastle.crypto.digests; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347. + */ +public class MD5Digest + extends GeneralDigest +{ + private static final int DIGEST_LENGTH = 16; + + private int H1, H2, H3, H4; // IV's + + private int[] X = new int[16]; + private int xOff; + + /** + * Standard constructor + */ + public MD5Digest() + { + reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public MD5Digest(MD5Digest t) + { + super(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + + System.arraycopy(t.X, 0, X, 0, t.X.length); + xOff = t.xOff; + } + + public String getAlgorithmName() + { + return "MD5"; + } + + public int getDigestSize() + { + return DIGEST_LENGTH; + } + + protected void processWord( + byte[] in, + int inOff) + { + X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) + | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24); + + if (xOff == 16) + { + processBlock(); + } + } + + protected void processLength( + long bitLength) + { + if (xOff > 14) + { + processBlock(); + } + + X[14] = (int)(bitLength & 0xffffffff); + X[15] = (int)(bitLength >>> 32); + } + + private void unpackWord( + int word, + byte[] out, + int outOff) + { + out[outOff] = (byte)word; + out[outOff + 1] = (byte)(word >>> 8); + out[outOff + 2] = (byte)(word >>> 16); + out[outOff + 3] = (byte)(word >>> 24); + } + + public int doFinal( + byte[] out, + int outOff) + { + finish(); + + unpackWord(H1, out, outOff); + unpackWord(H2, out, outOff + 4); + unpackWord(H3, out, outOff + 8); + unpackWord(H4, out, outOff + 12); + + reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables to the IV values. + */ + public void reset() + { + super.reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + + xOff = 0; + + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } + + // + // round 1 left rotates + // + private static final int S11 = 7; + private static final int S12 = 12; + private static final int S13 = 17; + private static final int S14 = 22; + + // + // round 2 left rotates + // + private static final int S21 = 5; + private static final int S22 = 9; + private static final int S23 = 14; + private static final int S24 = 20; + + // + // round 3 left rotates + // + private static final int S31 = 4; + private static final int S32 = 11; + private static final int S33 = 16; + private static final int S34 = 23; + + // + // round 4 left rotates + // + private static final int S41 = 6; + private static final int S42 = 10; + private static final int S43 = 15; + private static final int S44 = 21; + + /* + * rotate int x left n bits. + */ + private int rotateLeft( + int x, + int n) + { + return (x << n) | (x >>> (32 - n)); + } + + /* + * F, G, H and I are the basic MD5 functions. + */ + private int F( + int u, + int v, + int w) + { + return (u & v) | (~u & w); + } + + private int G( + int u, + int v, + int w) + { + return (u & w) | (v & ~w); + } + + private int H( + int u, + int v, + int w) + { + return u ^ v ^ w; + } + + private int K( + int u, + int v, + int w) + { + return v ^ (u | ~w); + } + + protected void processBlock() + { + int a = H1; + int b = H2; + int c = H3; + int d = H4; + + // + // Round 1 - F cycle, 16 times. + // + a = rotateLeft((a + F(b, c, d) + X[ 0] + 0xd76aa478), S11) + b; + d = rotateLeft((d + F(a, b, c) + X[ 1] + 0xe8c7b756), S12) + a; + c = rotateLeft((c + F(d, a, b) + X[ 2] + 0x242070db), S13) + d; + b = rotateLeft((b + F(c, d, a) + X[ 3] + 0xc1bdceee), S14) + c; + a = rotateLeft((a + F(b, c, d) + X[ 4] + 0xf57c0faf), S11) + b; + d = rotateLeft((d + F(a, b, c) + X[ 5] + 0x4787c62a), S12) + a; + c = rotateLeft((c + F(d, a, b) + X[ 6] + 0xa8304613), S13) + d; + b = rotateLeft((b + F(c, d, a) + X[ 7] + 0xfd469501), S14) + c; + a = rotateLeft((a + F(b, c, d) + X[ 8] + 0x698098d8), S11) + b; + d = rotateLeft((d + F(a, b, c) + X[ 9] + 0x8b44f7af), S12) + a; + c = rotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), S13) + d; + b = rotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), S14) + c; + a = rotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), S11) + b; + d = rotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), S12) + a; + c = rotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), S13) + d; + b = rotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), S14) + c; + + // + // Round 2 - G cycle, 16 times. + // + a = rotateLeft((a + G(b, c, d) + X[ 1] + 0xf61e2562), S21) + b; + d = rotateLeft((d + G(a, b, c) + X[ 6] + 0xc040b340), S22) + a; + c = rotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), S23) + d; + b = rotateLeft((b + G(c, d, a) + X[ 0] + 0xe9b6c7aa), S24) + c; + a = rotateLeft((a + G(b, c, d) + X[ 5] + 0xd62f105d), S21) + b; + d = rotateLeft((d + G(a, b, c) + X[10] + 0x02441453), S22) + a; + c = rotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), S23) + d; + b = rotateLeft((b + G(c, d, a) + X[ 4] + 0xe7d3fbc8), S24) + c; + a = rotateLeft((a + G(b, c, d) + X[ 9] + 0x21e1cde6), S21) + b; + d = rotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), S22) + a; + c = rotateLeft((c + G(d, a, b) + X[ 3] + 0xf4d50d87), S23) + d; + b = rotateLeft((b + G(c, d, a) + X[ 8] + 0x455a14ed), S24) + c; + a = rotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), S21) + b; + d = rotateLeft((d + G(a, b, c) + X[ 2] + 0xfcefa3f8), S22) + a; + c = rotateLeft((c + G(d, a, b) + X[ 7] + 0x676f02d9), S23) + d; + b = rotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), S24) + c; + + // + // Round 3 - H cycle, 16 times. + // + a = rotateLeft((a + H(b, c, d) + X[ 5] + 0xfffa3942), S31) + b; + d = rotateLeft((d + H(a, b, c) + X[ 8] + 0x8771f681), S32) + a; + c = rotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), S33) + d; + b = rotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), S34) + c; + a = rotateLeft((a + H(b, c, d) + X[ 1] + 0xa4beea44), S31) + b; + d = rotateLeft((d + H(a, b, c) + X[ 4] + 0x4bdecfa9), S32) + a; + c = rotateLeft((c + H(d, a, b) + X[ 7] + 0xf6bb4b60), S33) + d; + b = rotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), S34) + c; + a = rotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), S31) + b; + d = rotateLeft((d + H(a, b, c) + X[ 0] + 0xeaa127fa), S32) + a; + c = rotateLeft((c + H(d, a, b) + X[ 3] + 0xd4ef3085), S33) + d; + b = rotateLeft((b + H(c, d, a) + X[ 6] + 0x04881d05), S34) + c; + a = rotateLeft((a + H(b, c, d) + X[ 9] + 0xd9d4d039), S31) + b; + d = rotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), S32) + a; + c = rotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), S33) + d; + b = rotateLeft((b + H(c, d, a) + X[ 2] + 0xc4ac5665), S34) + c; + + // + // Round 4 - K cycle, 16 times. + // + a = rotateLeft((a + K(b, c, d) + X[ 0] + 0xf4292244), S41) + b; + d = rotateLeft((d + K(a, b, c) + X[ 7] + 0x432aff97), S42) + a; + c = rotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), S43) + d; + b = rotateLeft((b + K(c, d, a) + X[ 5] + 0xfc93a039), S44) + c; + a = rotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), S41) + b; + d = rotateLeft((d + K(a, b, c) + X[ 3] + 0x8f0ccc92), S42) + a; + c = rotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), S43) + d; + b = rotateLeft((b + K(c, d, a) + X[ 1] + 0x85845dd1), S44) + c; + a = rotateLeft((a + K(b, c, d) + X[ 8] + 0x6fa87e4f), S41) + b; + d = rotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), S42) + a; + c = rotateLeft((c + K(d, a, b) + X[ 6] + 0xa3014314), S43) + d; + b = rotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), S44) + c; + a = rotateLeft((a + K(b, c, d) + X[ 4] + 0xf7537e82), S41) + b; + d = rotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), S42) + a; + c = rotateLeft((c + K(d, a, b) + X[ 2] + 0x2ad7d2bb), S43) + d; + b = rotateLeft((b + K(c, d, a) + X[ 9] + 0xeb86d391), S44) + c; + + H1 += a; + H2 += b; + H3 += c; + H4 += d; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } +} diff --git a/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java b/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java new file mode 100644 index 0000000..3ab7459 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java @@ -0,0 +1,280 @@ +package org.bouncycastle.crypto.digests; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. + * + * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 + * is the "endienness" of the word processing! + */ +public class SHA1Digest + extends GeneralDigest +{ + private static final int DIGEST_LENGTH = 20; + + private int H1, H2, H3, H4, H5; + + private int[] X = new int[80]; + private int xOff; + + /** + * Standard constructor + */ + public SHA1Digest() + { + reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public SHA1Digest(SHA1Digest t) + { + super(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + + System.arraycopy(t.X, 0, X, 0, t.X.length); + xOff = t.xOff; + } + + public String getAlgorithmName() + { + return "SHA-1"; + } + + public int getDigestSize() + { + return DIGEST_LENGTH; + } + + protected void processWord( + byte[] in, + int inOff) + { + X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16) + | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff)); + + if (xOff == 16) + { + processBlock(); + } + } + + private void unpackWord( + int word, + byte[] out, + int outOff) + { + out[outOff] = (byte)(word >>> 24); + out[outOff + 1] = (byte)(word >>> 16); + out[outOff + 2] = (byte)(word >>> 8); + out[outOff + 3] = (byte)word; + } + + protected void processLength( + long bitLength) + { + if (xOff > 14) + { + processBlock(); + } + + X[14] = (int)(bitLength >>> 32); + X[15] = (int)(bitLength & 0xffffffff); + } + + public int doFinal( + byte[] out, + int outOff) + { + finish(); + + unpackWord(H1, out, outOff); + unpackWord(H2, out, outOff + 4); + unpackWord(H3, out, outOff + 8); + unpackWord(H4, out, outOff + 12); + unpackWord(H5, out, outOff + 16); + + reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables + */ + public void reset() + { + super.reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + H5 = 0xc3d2e1f0; + + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } + + // + // Additive constants + // + private static final int Y1 = 0x5a827999; + private static final int Y2 = 0x6ed9eba1; + private static final int Y3 = 0x8f1bbcdc; + private static final int Y4 = 0xca62c1d6; + + private int f( + int u, + int v, + int w) + { + return ((u & v) | ((~u) & w)); + } + + private int h( + int u, + int v, + int w) + { + return (u ^ v ^ w); + } + + private int g( + int u, + int v, + int w) + { + return ((u & v) | (u & w) | (v & w)); + } + + private int rotateLeft( + int x, + int n) + { + return (x << n) | (x >>> (32 - n)); + } + + protected void processBlock() + { + // + // expand 16 word block into 80 word block. + // + for (int i = 16; i <= 79; i++) + { + X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1); + } + + // + // set up working variables. + // + int A = H1; + int B = H2; + int C = H3; + int D = H4; + int E = H5; + + // + // round 1 + // + for (int j = 0; j <= 19; j++) + { + int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 2 + // + for (int j = 20; j <= 39; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 3 + // + for (int j = 40; j <= 59; j++) + { + int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 4 + // + for (int j = 60; j <= 79; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + H1 += A; + H2 += B; + H3 += C; + H4 += D; + H5 += E; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } +} diff --git a/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java new file mode 100644 index 0000000..be17280 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java @@ -0,0 +1,550 @@ +package org.bouncycastle.crypto.engines; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.params.KeyParameter; + +/** + * an implementation of the AES (Rijndael), from FIPS-197. + *

+ * For further details see: http://csrc.nist.gov/encryption/aes/. + * + * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + * http://fp.gladman.plus.com/cryptography_technology/rijndael/ + * + * There are three levels of tradeoff of speed vs memory + * Because java has no preprocessor, they are written as three separate classes from which to choose + * + * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption + * and 4 for decryption. + * + * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, + * adding 12 rotate operations per round to compute the values contained in the other tables from + * the contents of the first. + * + * The slowest version uses no static tables at all and computes the values in each round. + *

+ * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. + * + */ +public class AESEngine + implements BlockCipher +{ + // The S box + private static final byte[] S = { + (byte)99, (byte)124, (byte)119, (byte)123, (byte)242, (byte)107, (byte)111, (byte)197, + (byte)48, (byte)1, (byte)103, (byte)43, (byte)254, (byte)215, (byte)171, (byte)118, + (byte)202, (byte)130, (byte)201, (byte)125, (byte)250, (byte)89, (byte)71, (byte)240, + (byte)173, (byte)212, (byte)162, (byte)175, (byte)156, (byte)164, (byte)114, (byte)192, + (byte)183, (byte)253, (byte)147, (byte)38, (byte)54, (byte)63, (byte)247, (byte)204, + (byte)52, (byte)165, (byte)229, (byte)241, (byte)113, (byte)216, (byte)49, (byte)21, + (byte)4, (byte)199, (byte)35, (byte)195, (byte)24, (byte)150, (byte)5, (byte)154, + (byte)7, (byte)18, (byte)128, (byte)226, (byte)235, (byte)39, (byte)178, (byte)117, + (byte)9, (byte)131, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte)160, + (byte)82, (byte)59, (byte)214, (byte)179, (byte)41, (byte)227, (byte)47, (byte)132, + (byte)83, (byte)209, (byte)0, (byte)237, (byte)32, (byte)252, (byte)177, (byte)91, + (byte)106, (byte)203, (byte)190, (byte)57, (byte)74, (byte)76, (byte)88, (byte)207, + (byte)208, (byte)239, (byte)170, (byte)251, (byte)67, (byte)77, (byte)51, (byte)133, + (byte)69, (byte)249, (byte)2, (byte)127, (byte)80, (byte)60, (byte)159, (byte)168, + (byte)81, (byte)163, (byte)64, (byte)143, (byte)146, (byte)157, (byte)56, (byte)245, + (byte)188, (byte)182, (byte)218, (byte)33, (byte)16, (byte)255, (byte)243, (byte)210, + (byte)205, (byte)12, (byte)19, (byte)236, (byte)95, (byte)151, (byte)68, (byte)23, + (byte)196, (byte)167, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, + (byte)96, (byte)129, (byte)79, (byte)220, (byte)34, (byte)42, (byte)144, (byte)136, + (byte)70, (byte)238, (byte)184, (byte)20, (byte)222, (byte)94, (byte)11, (byte)219, + (byte)224, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, + (byte)194, (byte)211, (byte)172, (byte)98, (byte)145, (byte)149, (byte)228, (byte)121, + (byte)231, (byte)200, (byte)55, (byte)109, (byte)141, (byte)213, (byte)78, (byte)169, + (byte)108, (byte)86, (byte)244, (byte)234, (byte)101, (byte)122, (byte)174, (byte)8, + (byte)186, (byte)120, (byte)37, (byte)46, (byte)28, (byte)166, (byte)180, (byte)198, + (byte)232, (byte)221, (byte)116, (byte)31, (byte)75, (byte)189, (byte)139, (byte)138, + (byte)112, (byte)62, (byte)181, (byte)102, (byte)72, (byte)3, (byte)246, (byte)14, + (byte)97, (byte)53, (byte)87, (byte)185, (byte)134, (byte)193, (byte)29, (byte)158, + (byte)225, (byte)248, (byte)152, (byte)17, (byte)105, (byte)217, (byte)142, (byte)148, + (byte)155, (byte)30, (byte)135, (byte)233, (byte)206, (byte)85, (byte)40, (byte)223, + (byte)140, (byte)161, (byte)137, (byte)13, (byte)191, (byte)230, (byte)66, (byte)104, + (byte)65, (byte)153, (byte)45, (byte)15, (byte)176, (byte)84, (byte)187, (byte)22, + }; + + // The inverse S-box + private static final byte[] Si = { + (byte)82, (byte)9, (byte)106, (byte)213, (byte)48, (byte)54, (byte)165, (byte)56, + (byte)191, (byte)64, (byte)163, (byte)158, (byte)129, (byte)243, (byte)215, (byte)251, + (byte)124, (byte)227, (byte)57, (byte)130, (byte)155, (byte)47, (byte)255, (byte)135, + (byte)52, (byte)142, (byte)67, (byte)68, (byte)196, (byte)222, (byte)233, (byte)203, + (byte)84, (byte)123, (byte)148, (byte)50, (byte)166, (byte)194, (byte)35, (byte)61, + (byte)238, (byte)76, (byte)149, (byte)11, (byte)66, (byte)250, (byte)195, (byte)78, + (byte)8, (byte)46, (byte)161, (byte)102, (byte)40, (byte)217, (byte)36, (byte)178, + (byte)118, (byte)91, (byte)162, (byte)73, (byte)109, (byte)139, (byte)209, (byte)37, + (byte)114, (byte)248, (byte)246, (byte)100, (byte)134, (byte)104, (byte)152, (byte)22, + (byte)212, (byte)164, (byte)92, (byte)204, (byte)93, (byte)101, (byte)182, (byte)146, + (byte)108, (byte)112, (byte)72, (byte)80, (byte)253, (byte)237, (byte)185, (byte)218, + (byte)94, (byte)21, (byte)70, (byte)87, (byte)167, (byte)141, (byte)157, (byte)132, + (byte)144, (byte)216, (byte)171, (byte)0, (byte)140, (byte)188, (byte)211, (byte)10, + (byte)247, (byte)228, (byte)88, (byte)5, (byte)184, (byte)179, (byte)69, (byte)6, + (byte)208, (byte)44, (byte)30, (byte)143, (byte)202, (byte)63, (byte)15, (byte)2, + (byte)193, (byte)175, (byte)189, (byte)3, (byte)1, (byte)19, (byte)138, (byte)107, + (byte)58, (byte)145, (byte)17, (byte)65, (byte)79, (byte)103, (byte)220, (byte)234, + (byte)151, (byte)242, (byte)207, (byte)206, (byte)240, (byte)180, (byte)230, (byte)115, + (byte)150, (byte)172, (byte)116, (byte)34, (byte)231, (byte)173, (byte)53, (byte)133, + (byte)226, (byte)249, (byte)55, (byte)232, (byte)28, (byte)117, (byte)223, (byte)110, + (byte)71, (byte)241, (byte)26, (byte)113, (byte)29, (byte)41, (byte)197, (byte)137, + (byte)111, (byte)183, (byte)98, (byte)14, (byte)170, (byte)24, (byte)190, (byte)27, + (byte)252, (byte)86, (byte)62, (byte)75, (byte)198, (byte)210, (byte)121, (byte)32, + (byte)154, (byte)219, (byte)192, (byte)254, (byte)120, (byte)205, (byte)90, (byte)244, + (byte)31, (byte)221, (byte)168, (byte)51, (byte)136, (byte)7, (byte)199, (byte)49, + (byte)177, (byte)18, (byte)16, (byte)89, (byte)39, (byte)128, (byte)236, (byte)95, + (byte)96, (byte)81, (byte)127, (byte)169, (byte)25, (byte)181, (byte)74, (byte)13, + (byte)45, (byte)229, (byte)122, (byte)159, (byte)147, (byte)201, (byte)156, (byte)239, + (byte)160, (byte)224, (byte)59, (byte)77, (byte)174, (byte)42, (byte)245, (byte)176, + (byte)200, (byte)235, (byte)187, (byte)60, (byte)131, (byte)83, (byte)153, (byte)97, + (byte)23, (byte)43, (byte)4, (byte)126, (byte)186, (byte)119, (byte)214, (byte)38, + (byte)225, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125, + }; + + // vector used in calculating key schedule (powers of x in GF(256)) + private static final int[] rcon = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; + + // precomputation tables of calculations for rounds + private static final int[] T0 = + { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, + 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, + 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, + 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, + 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, + 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, + 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, + 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, + 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, + 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, + 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, + 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, + 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, + 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, + 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, + 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, + 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, + 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, + 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, + 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, + 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, + 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, + 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, + 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, + 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, + 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, + 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, + 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, + 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, + 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, + 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, + 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, + 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, + 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, + 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, + 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, + 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, + 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, + 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, + 0x3a16162c}; + +private static final int[] Tinv0 = + { + 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, + 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, + 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, + 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, + 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, + 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, + 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, + 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, + 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, + 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, + 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, + 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, + 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, + 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, + 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, + 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, + 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, + 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, + 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, + 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, + 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, + 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, + 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, + 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, + 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, + 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, + 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, + 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, + 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, + 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, + 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, + 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, + 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, + 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, + 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, + 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, + 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, + 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, + 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, + 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, + 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, + 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, + 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, + 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, + 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, + 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, + 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, + 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, + 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, + 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, + 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, + 0x4257b8d0}; + + private int shift( + int r, + int shift) + { + return (((r >>> shift) | (r << (32 - shift)))); + } + + /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + + private static final int m1 = 0x80808080; + private static final int m2 = 0x7f7f7f7f; + private static final int m3 = 0x0000001b; + private int FFmulX(int x) { + return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3)); + } + + /* + The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. + + private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); } + private static final int m4 = 0x1b1b1b1b; + private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); } + + */ + + private int inv_mcol(int x) { + int f2 = FFmulX(x); + int f4 = FFmulX(f2); + int f8 = FFmulX(f4); + int f9 = x ^ f8; + + return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24); + } + + private int subWord(int x) { + return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24); + } + + /** + * Calculate the necessary round keys + * The number of calculations depends on key size and block size + * AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits + * This code is written assuming those are the only possible values + */ + private int[][] generateWorkingKey( + byte[] key, + boolean forEncryption) + { + int KC = key.length / 4; // key length in words + int t; + + if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length)) { + throw new IllegalArgumentException("Key length not 128/192/256 bits."); + } + + ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes + int[][] W = new int[ROUNDS+1][4]; // 4 words in a block + + // + // copy the key into the round key array + // + + t = 0; + for (int i = 0; i < key.length; t++) + { + W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24); + i+=4; + } + + // + // while not enough round key material calculated + // calculate new values + // + int k = (ROUNDS + 1) << 2; + for (int i = KC; (i < k); i++) + { + int temp = W[(i-1)>>2][(i-1)&3]; + if ((i % KC) == 0) { + temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1]; + } else if ((KC > 6) && ((i % KC) == 4)) { + temp = subWord(temp); + } + + W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp; + } + + if (!forEncryption) { + for (int j = 1; j < ROUNDS; j++) { + for (int i = 0; i < 4; i++){ + W[j][i] = inv_mcol(W[j][i]); + } + } + } + + return W; + } + + private int ROUNDS; + private int[][] WorkingKey = null; + private int C0, C1, C2, C3; + private boolean forEncryption; + + private static final int BLOCK_SIZE = 16; + + /** + * default constructor - 128 bit block size. + */ + public AESEngine() + { + } + + /** + * initialise an AES cipher. + * + * @param forEncryption whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception IllegalArgumentException if the params argument is + * inappropriate. + */ + public void init( + boolean forEncryption, + CipherParameters params) + { + if (params instanceof KeyParameter) + { + WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption); + this.forEncryption = forEncryption; + return; + } + + throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName()); + } + + public String getAlgorithmName() + { + return "AES"; + } + + public int getBlockSize() + { + return BLOCK_SIZE; + } + + public int processBlock( + byte[] in, + int inOff, + byte[] out, + int outOff) + { + if (WorkingKey == null) + { + throw new IllegalStateException("AES engine not initialised"); + } + + if ((inOff + (32 / 2)) > in.length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + (32 / 2)) > out.length) + { + throw new DataLengthException("output buffer too short"); + } + + if (forEncryption) + { + unpackBlock(in, inOff); + encryptBlock(WorkingKey); + packBlock(out, outOff); + } + else + { + unpackBlock(in, inOff); + decryptBlock(WorkingKey); + packBlock(out, outOff); + } + + return BLOCK_SIZE; + } + + public void reset() + { + } + + private final void unpackBlock( + byte[] bytes, + int off) + { + int index = off; + + C0 = (bytes[index++] & 0xff); + C0 |= (bytes[index++] & 0xff) << 8; + C0 |= (bytes[index++] & 0xff) << 16; + C0 |= bytes[index++] << 24; + + C1 = (bytes[index++] & 0xff); + C1 |= (bytes[index++] & 0xff) << 8; + C1 |= (bytes[index++] & 0xff) << 16; + C1 |= bytes[index++] << 24; + + C2 = (bytes[index++] & 0xff); + C2 |= (bytes[index++] & 0xff) << 8; + C2 |= (bytes[index++] & 0xff) << 16; + C2 |= bytes[index++] << 24; + + C3 = (bytes[index++] & 0xff); + C3 |= (bytes[index++] & 0xff) << 8; + C3 |= (bytes[index++] & 0xff) << 16; + C3 |= bytes[index++] << 24; + } + + private final void packBlock( + byte[] bytes, + int off) + { + int index = off; + + bytes[index++] = (byte)C0; + bytes[index++] = (byte)(C0 >> 8); + bytes[index++] = (byte)(C0 >> 16); + bytes[index++] = (byte)(C0 >> 24); + + bytes[index++] = (byte)C1; + bytes[index++] = (byte)(C1 >> 8); + bytes[index++] = (byte)(C1 >> 16); + bytes[index++] = (byte)(C1 >> 24); + + bytes[index++] = (byte)C2; + bytes[index++] = (byte)(C2 >> 8); + bytes[index++] = (byte)(C2 >> 16); + bytes[index++] = (byte)(C2 >> 24); + + bytes[index++] = (byte)C3; + bytes[index++] = (byte)(C3 >> 8); + bytes[index++] = (byte)(C3 >> 16); + bytes[index++] = (byte)(C3 >> 24); + } + + + private final void encryptBlock(int[][] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[0][0]; + C1 ^= KW[0][1]; + C2 ^= KW[0][2]; + C3 ^= KW[0][3]; + + for (r = 1; r < ROUNDS - 1;) { + r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255],16) ^ shift(T0[(C3>>24)&255],8) ^ KW[r][0]; + r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; + r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; + r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; + C0 = T0[r0&255] ^ shift(T0[(r1>>8)&255], 24) ^ shift(T0[(r2>>16)&255], 16) ^ shift(T0[(r3>>24)&255], 8) ^ KW[r][0]; + C1 = T0[r1&255] ^ shift(T0[(r2>>8)&255], 24) ^ shift(T0[(r3>>16)&255], 16) ^ shift(T0[(r0>>24)&255], 8) ^ KW[r][1]; + C2 = T0[r2&255] ^ shift(T0[(r3>>8)&255], 24) ^ shift(T0[(r0>>16)&255], 16) ^ shift(T0[(r1>>24)&255], 8) ^ KW[r][2]; + C3 = T0[r3&255] ^ shift(T0[(r0>>8)&255], 24) ^ shift(T0[(r1>>16)&255], 16) ^ shift(T0[(r2>>24)&255], 8) ^ KW[r++][3]; + } + + r0 = T0[C0&255] ^ shift(T0[(C1>>8)&255], 24) ^ shift(T0[(C2>>16)&255], 16) ^ shift(T0[(C3>>24)&255], 8) ^ KW[r][0]; + r1 = T0[C1&255] ^ shift(T0[(C2>>8)&255], 24) ^ shift(T0[(C3>>16)&255], 16) ^ shift(T0[(C0>>24)&255], 8) ^ KW[r][1]; + r2 = T0[C2&255] ^ shift(T0[(C3>>8)&255], 24) ^ shift(T0[(C0>>16)&255], 16) ^ shift(T0[(C1>>24)&255], 8) ^ KW[r][2]; + r3 = T0[C3&255] ^ shift(T0[(C0>>8)&255], 24) ^ shift(T0[(C1>>16)&255], 16) ^ shift(T0[(C2>>24)&255], 8) ^ KW[r++][3]; + + // the final round's table is a simple function of S so we don't use a whole other four tables for it + + C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0]; + C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1]; + C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2]; + C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3]; + + } + + private final void decryptBlock(int[][] KW) + { + int r, r0, r1, r2, r3; + + C0 ^= KW[ROUNDS][0]; + C1 ^= KW[ROUNDS][1]; + C2 ^= KW[ROUNDS][2]; + C3 ^= KW[ROUNDS][3]; + + for (r = ROUNDS-1; r>1;) { + r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; + r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; + r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; + r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r--][3]; + C0 = Tinv0[r0&255] ^ shift(Tinv0[(r3>>8)&255], 24) ^ shift(Tinv0[(r2>>16)&255], 16) ^ shift(Tinv0[(r1>>24)&255], 8) ^ KW[r][0]; + C1 = Tinv0[r1&255] ^ shift(Tinv0[(r0>>8)&255], 24) ^ shift(Tinv0[(r3>>16)&255], 16) ^ shift(Tinv0[(r2>>24)&255], 8) ^ KW[r][1]; + C2 = Tinv0[r2&255] ^ shift(Tinv0[(r1>>8)&255], 24) ^ shift(Tinv0[(r0>>16)&255], 16) ^ shift(Tinv0[(r3>>24)&255], 8) ^ KW[r][2]; + C3 = Tinv0[r3&255] ^ shift(Tinv0[(r2>>8)&255], 24) ^ shift(Tinv0[(r1>>16)&255], 16) ^ shift(Tinv0[(r0>>24)&255], 8) ^ KW[r--][3]; + } + + r0 = Tinv0[C0&255] ^ shift(Tinv0[(C3>>8)&255], 24) ^ shift(Tinv0[(C2>>16)&255], 16) ^ shift(Tinv0[(C1>>24)&255], 8) ^ KW[r][0]; + r1 = Tinv0[C1&255] ^ shift(Tinv0[(C0>>8)&255], 24) ^ shift(Tinv0[(C3>>16)&255], 16) ^ shift(Tinv0[(C2>>24)&255], 8) ^ KW[r][1]; + r2 = Tinv0[C2&255] ^ shift(Tinv0[(C1>>8)&255], 24) ^ shift(Tinv0[(C0>>16)&255], 16) ^ shift(Tinv0[(C3>>24)&255], 8) ^ KW[r][2]; + r3 = Tinv0[C3&255] ^ shift(Tinv0[(C2>>8)&255], 24) ^ shift(Tinv0[(C1>>16)&255], 16) ^ shift(Tinv0[(C0>>24)&255], 8) ^ KW[r--][3]; + + // the final round's table is a simple function of Si so we don't use a whole other four tables for it + + C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0]; + C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1]; + C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2]; + C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3]; + } +} diff --git a/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java b/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java new file mode 100644 index 0000000..59541b3 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java @@ -0,0 +1,511 @@ +package org.bouncycastle.crypto.engines; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.params.KeyParameter; + +/** + * a class that provides a basic DES engine. + */ +public class DESEngine + implements BlockCipher +{ + protected static final int BLOCK_SIZE = 8; + + private int[] workingKey = null; + + /** + * standard constructor. + */ + public DESEngine() + { + } + + /** + * initialise a DES cipher. + * + * @param encrypting whether or not we are for encryption. + * @param params the parameters required to set up the cipher. + * @exception IllegalArgumentException if the params argument is + * inappropriate. + */ + public void init( + boolean encrypting, + CipherParameters params) + { + if (params instanceof KeyParameter) + { + workingKey = generateWorkingKey(encrypting, + ((KeyParameter)params).getKey()); + + return; + } + + throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName()); + } + + public String getAlgorithmName() + { + return "DES"; + } + + public int getBlockSize() + { + return BLOCK_SIZE; + } + + public int processBlock( + byte[] in, + int inOff, + byte[] out, + int outOff) + { + if (workingKey == null) + { + throw new IllegalStateException("DES engine not initialised"); + } + + if ((inOff + BLOCK_SIZE) > in.length) + { + throw new DataLengthException("input buffer too short"); + } + + if ((outOff + BLOCK_SIZE) > out.length) + { + throw new DataLengthException("output buffer too short"); + } + + desFunc(workingKey, in, inOff, out, outOff); + + return BLOCK_SIZE; + } + + public void reset() + { + } + + /** + * what follows is mainly taken from "Applied Cryptography", by + * Bruce Schneier, however it also bears great resemblance to Richard + * Outerbridge's D3DES... + */ + + static short[] Df_Key = + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 + }; + + static short[] bytebit = + { + 0200, 0100, 040, 020, 010, 04, 02, 01 + }; + + static int[] bigbyte = + { + 0x800000, 0x400000, 0x200000, 0x100000, + 0x80000, 0x40000, 0x20000, 0x10000, + 0x8000, 0x4000, 0x2000, 0x1000, + 0x800, 0x400, 0x200, 0x100, + 0x80, 0x40, 0x20, 0x10, + 0x8, 0x4, 0x2, 0x1 + }; + + /* + * Use the key schedule specified in the Standard (ANSI X3.92-1981). + */ + + static byte[] pc1 = + { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 + }; + + static byte[] totrot = + { + 1, 2, 4, 6, 8, 10, 12, 14, + 15, 17, 19, 21, 23, 25, 27, 28 + }; + + static byte[] pc2 = + { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 + }; + + static int[] SP1 = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 + }; + + static int[] SP2 = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 + }; + + static int[] SP3 = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 + }; + + static int[] SP4 = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 + }; + + static int[] SP5 = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 + }; + + static int[] SP6 = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 + }; + + static int[] SP7 = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 + }; + + static int[] SP8 = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 + }; + + /** + * generate an integer based working key based on our secret key + * and what we processing we are planning to do. + * + * Acknowledgements for this routine go to James Gillogly & Phil Karn. + * (whoever, and wherever they are!). + */ + protected int[] generateWorkingKey( + boolean encrypting, + byte[] key) + { + int[] newKey = new int[32]; + boolean[] pc1m = new boolean[56], + pcr = new boolean[56]; + + for (int j = 0; j < 56; j++ ) + { + int l = pc1[j]; + + pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0); + } + + for (int i = 0; i < 16; i++) + { + int l, m, n; + + if (encrypting) + { + m = i << 1; + } + else + { + m = (15 - i) << 1; + } + + n = m + 1; + newKey[m] = newKey[n] = 0; + + for (int j = 0; j < 28; j++) + { + l = j + totrot[i]; + if ( l < 28 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 28; j < 56; j++) + { + l = j + totrot[i]; + if (l < 56 ) + { + pcr[j] = pc1m[l]; + } + else + { + pcr[j] = pc1m[l - 28]; + } + } + + for (int j = 0; j < 24; j++) + { + if (pcr[pc2[j]]) + { + newKey[m] |= bigbyte[j]; + } + + if (pcr[pc2[j + 24]]) + { + newKey[n] |= bigbyte[j]; + } + } + } + + // + // store the processed key + // + for (int i = 0; i != 32; i += 2) + { + int i1, i2; + + i1 = newKey[i]; + i2 = newKey[i + 1]; + + newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) + | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6); + + newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) + | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f); + } + + return newKey; + } + + /** + * the DES engine. + */ + protected void desFunc( + int[] wKey, + byte[] in, + int inOff, + byte[] out, + int outOff) + { + int work, right, left; + + left = (in[inOff + 0] & 0xff) << 24; + left |= (in[inOff + 1] & 0xff) << 16; + left |= (in[inOff + 2] & 0xff) << 8; + left |= (in[inOff + 3] & 0xff); + + right = (in[inOff + 4] & 0xff) << 24; + right |= (in[inOff + 5] & 0xff) << 16; + right |= (in[inOff + 6] & 0xff) << 8; + right |= (in[inOff + 7] & 0xff); + + work = ((left >>> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= (work << 4); + work = ((left >>> 16) ^ right) & 0x0000ffff; + right ^= work; + left ^= (work << 16); + work = ((right >>> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >>> 8) ^ left) & 0x00ff00ff; + left ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff; + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff; + + for (int round = 0; round < 8; round++) + { + int fval; + + work = (right << 28) | (right >>> 4); + work ^= wKey[round * 4 + 0]; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >>> 8) & 0x3f]; + fval |= SP3[(work >>> 16) & 0x3f]; + fval |= SP1[(work >>> 24) & 0x3f]; + work = right ^ wKey[round * 4 + 1]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >>> 8) & 0x3f]; + fval |= SP4[(work >>> 16) & 0x3f]; + fval |= SP2[(work >>> 24) & 0x3f]; + left ^= fval; + work = (left << 28) | (left >>> 4); + work ^= wKey[round * 4 + 2]; + fval = SP7[ work & 0x3f]; + fval |= SP5[(work >>> 8) & 0x3f]; + fval |= SP3[(work >>> 16) & 0x3f]; + fval |= SP1[(work >>> 24) & 0x3f]; + work = left ^ wKey[round * 4 + 3]; + fval |= SP8[ work & 0x3f]; + fval |= SP6[(work >>> 8) & 0x3f]; + fval |= SP4[(work >>> 16) & 0x3f]; + fval |= SP2[(work >>> 24) & 0x3f]; + right ^= fval; + } + + right = (right << 31) | (right >>> 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = (left << 31) | (left >>> 1); + work = ((left >>> 8) ^ right) & 0x00ff00ff; + right ^= work; + left ^= (work << 8); + work = ((left >>> 2) ^ right) & 0x33333333; + right ^= work; + left ^= (work << 2); + work = ((right >>> 16) ^ left) & 0x0000ffff; + left ^= work; + right ^= (work << 16); + work = ((right >>> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= (work << 4); + + out[outOff + 0] = (byte)((right >>> 24) & 0xff); + out[outOff + 1] = (byte)((right >>> 16) & 0xff); + out[outOff + 2] = (byte)((right >>> 8) & 0xff); + out[outOff + 3] = (byte)( right & 0xff); + out[outOff + 4] = (byte)((left >>> 24) & 0xff); + out[outOff + 5] = (byte)((left >>> 16) & 0xff); + out[outOff + 6] = (byte)((left >>> 8) & 0xff); + out[outOff + 7] = (byte)( left & 0xff); + } +} diff --git a/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java b/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java new file mode 100644 index 0000000..f8129c5 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/generators/DESKeyGenerator.java @@ -0,0 +1,45 @@ +package org.bouncycastle.crypto.generators; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import org.bouncycastle.crypto.CipherKeyGenerator; +import org.bouncycastle.crypto.params.DESParameters; + +public class DESKeyGenerator + extends CipherKeyGenerator +{ + public byte[] generateKey() + { + byte[] newKey = new byte[DESParameters.DES_KEY_LENGTH]; + + do + { + random.nextBytes(newKey); + + DESParameters.setOddParity(newKey); + } + while (DESParameters.isWeakKey(newKey, 0)); + + return newKey; + } +} diff --git a/src/main/java/org/bouncycastle/crypto/params/DESParameters.java b/src/main/java/org/bouncycastle/crypto/params/DESParameters.java new file mode 100644 index 0000000..f19dfec --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/params/DESParameters.java @@ -0,0 +1,129 @@ +package org.bouncycastle.crypto.params; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +public class DESParameters + extends KeyParameter +{ + public DESParameters( + byte[] key) + { + super(key); + + if (isWeakKey(key, 0)) + { + throw new IllegalArgumentException("attempt to create weak DES key"); + } + } + + /* + * DES Key length in bytes. + */ + static public final int DES_KEY_LENGTH = 8; + + /* + * Table of weak and semi-weak keys taken from Schneier pp281 + */ + static private final int N_DES_WEAK_KEYS = 16; + + static private byte[] DES_weak_keys = + { + /* weak keys */ + (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, + (byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e, + (byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1, + (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, + + /* semi-weak keys */ + (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, + (byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1, + (byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1, + (byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe, + (byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e, + (byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe, + (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, + (byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e, + (byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01, + (byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e, + (byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01, + (byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 + }; + + /** + * DES has 16 weak keys. This method will check + * if the given DES key material is weak or semi-weak. + * Key material that is too short is regarded as weak. + *

+ * See "Applied + * Cryptography" by Bruce Schneier for more information. + * + * @return true if the given DES key material is weak or semi-weak, + * false otherwise. + */ + public static boolean isWeakKey( + byte[] key, + int offset) + { + if (key.length - offset < DES_KEY_LENGTH) + { + throw new IllegalArgumentException("key material too short."); + } + + nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) + { + for (int j = 0; j < DES_KEY_LENGTH; j++) + { + if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j]) + { + continue nextkey; + } + } + + return true; + } + return false; + } + + /** + * DES Keys use the LSB as the odd parity bit. This can + * be used to check for corrupt keys. + * + * @param bytes the byte array to set the parity on. + */ + public static void setOddParity( + byte[] bytes) + { + for (int i = 0; i < bytes.length; i++) + { + int b = bytes[i]; + bytes[i] = (byte)((b & 0xfe) | + ((((b >> 1) ^ + (b >> 2) ^ + (b >> 3) ^ + (b >> 4) ^ + (b >> 5) ^ + (b >> 6) ^ + (b >> 7)) ^ 0x01) & 0x01)); + } + } +} diff --git a/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java b/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java new file mode 100644 index 0000000..5da2dff --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java @@ -0,0 +1,52 @@ +package org.bouncycastle.crypto.params; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import org.bouncycastle.crypto.CipherParameters; + +public class KeyParameter + implements CipherParameters +{ + private byte[] key; + + public KeyParameter( + byte[] key) + { + this(key, 0, key.length); + } + + public KeyParameter( + byte[] key, + int keyOff, + int keyLen) + { + this.key = new byte[keyLen]; + + System.arraycopy(key, keyOff, this.key, 0, keyLen); + } + + public byte[] getKey() + { + return key; + } +} diff --git a/src/main/java/org/sentrysoftware/example/Example.java b/src/main/java/org/sentrysoftware/example/Example.java deleted file mode 100644 index 211d94a..0000000 --- a/src/main/java/org/sentrysoftware/example/Example.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.sentrysoftware.example; - -/*- - * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ - * MY PROJECT - * ჻჻჻჻჻჻ - * Copyright 2023 Sentry Software - * ჻჻჻჻჻჻ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ - */ - -/** - * An Example class - */ -public class Example { - - /** - * The main function - */ - public static void main() { - System.out.println("Hello Open-source World!"); - } -} diff --git a/src/main/java/org/sentrysoftware/snmp/client/SnmpClient.java b/src/main/java/org/sentrysoftware/snmp/client/SnmpClient.java new file mode 100644 index 0000000..7b404f2 --- /dev/null +++ b/src/main/java/org/sentrysoftware/snmp/client/SnmpClient.java @@ -0,0 +1,573 @@ +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +package org.sentrysoftware.snmp.client; + +import uk.co.westhawk.snmp.pdu.BlockPdu; +import uk.co.westhawk.snmp.stack.AsnObject; +import uk.co.westhawk.snmp.stack.AsnObjectId; +import uk.co.westhawk.snmp.stack.AsnOctets; +import uk.co.westhawk.snmp.stack.PduException; +import uk.co.westhawk.snmp.stack.SnmpConstants; +import uk.co.westhawk.snmp.stack.SnmpContext; +import uk.co.westhawk.snmp.stack.SnmpContextv2c; +import uk.co.westhawk.snmp.stack.SnmpContextv3; +import uk.co.westhawk.snmp.stack.SnmpContextv3Face; +import uk.co.westhawk.snmp.stack.varbind; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class SnmpClient +{ + // Default SNMP port number + static public final int SNMP_PORT = 161; + + // SNMP v1, v2c, v3 + static public final int SNMP_V1 = 1; + static public final int SNMP_V2C = 2; + static public final int SNMP_V3 = 3; + static public final String SNMP_AUTH_MD5 = "MD5"; + static public final String SNMP_AUTH_SHA = "SHA"; + static public final String SNMP_PRIVACY_DES = "DES"; + static public final String SNMP_PRIVACY_AES = "AES"; + static public final String SNMP_NONE = "None"; + + + private SnmpContext contextv1 = null; + private SnmpContextv2c contextv2c = null; + private SnmpContextv3 contextv3 = null; + private BlockPdu pdu; + private String host; + private int port; + private String community; + private int snmpVersion; + private String authUsername; + private String authType; + private String authPassword; + private String privacyType; + private String privacyPassword; + private int[] retryIntervals; + private String contextName; + private byte[] contextEngineID; + static public final String SOCKET_TYPE = "Standard"; + + /** + * Creates an SNMPClient instance, which connects to the specified SNMP agent with the specified credentials + * (depending on the version of SNMP) + * @param host The hostname/IP address of the SNMP agent we're querying + * @param port The port of the SNMP agent (should be 161) + * @param version The version of SNMP to use (1, 2 or 3) + * @param retryIntervals Timeout in milliseconds after which the elementary operations will be retried + * @param community (SNMP v1 and v2 only) The SNMP community + * @param authType (SNMP v3 only) The authentication method: "MD5", "SHA" or "" + * @param authUsername (SNMP v3 only) The username + * @param authPassword (SNMP v3 only) The password (in clear) + * @param privacyType (SNMP v3 only) The encryption type: "DES", "AES" or "" + * @param privacyPassword (SNMP v3 only) The encryption password + * @param contextName (SNMP v3 only) The context name + * @param contextID (SNMP v3 only) The context ID (??) + * @throws IllegalArgumentException when specified authType, privType are invalid + * @throws IllegalStateException when the specified properties lead to something that cannot work (i.e. privacy without authentication) + * @throws IOException when cannot initialize the SNMP context + */ + public SnmpClient(String host, int port, int version, int[] retryIntervals, + String community, + String authType, String authUsername, String authPassword, + String privacyType, String privacyPassword, + String contextName, byte[] contextID) throws IOException { + // First, validate the inputs + validate(version, authType, privacyType); + + // Sets the attributes of the class instance + this.host = host; + this.port = port; + this.snmpVersion = version; + this.retryIntervals = retryIntervals; + this.community = community; + this.authType = authType; + this.authUsername = authUsername; + this.authPassword = authPassword; + this.privacyType = privacyType; + this.privacyPassword = privacyPassword; + this.contextName = contextName; + this.contextEngineID = contextID; + + // Properly create the SNMP context, based on these properties + initialize(); + } + + + /** + * Validate the specified inputs. Throws an IllegalArgumentException if needed. + * @param version Specified version of the SNMP protocol + * @param authType Specified authType + * @param privacyType Specified privacyType + * @throws IllegalArgumentException when invalid inputs are specified + */ + private void validate(int version, String authType, String privacyType) { + + // In case of SNMP v3, check the authType and privType (if not empty) + if (version == SNMP_V3) { + if (authType != null) { + if (!authType.isEmpty()) { + if (!authType.equals(SNMP_AUTH_MD5) && !authType.equals(SNMP_AUTH_SHA)) { + throw new IllegalArgumentException("Invalid authentication method '" + authType + "' (must be either '" + SNMP_AUTH_MD5 + "' or '" + SNMP_AUTH_SHA + "' or empty)"); + } + } + } + + if (privacyType != null) { + if (!privacyType.isEmpty()) { + if (!privacyType.equals(SNMP_PRIVACY_DES) && !privacyType.equals(SNMP_PRIVACY_AES)) { + throw new IllegalArgumentException("Invalid privacy method '" + privacyType +"' (must be either '" + SNMP_PRIVACY_DES + "' or '" + SNMP_PRIVACY_AES + "' or empty)"); + } + } + } + } + } + + /** + * Initialize the SNMPClient + *

+ * Creates the context to connect to the SNMP agent. Required before any actual operation is performed. + * @throws IOException when cannot create the SNMP context + * @throws IllegalStateException when there is an inconsistency in the properties that prevent us from moving forward + */ + private void initialize() throws IOException { + + // SNMP v2c + if (snmpVersion == SNMP_V2C) { + contextv2c = new SnmpContextv2c(host, port, null, SOCKET_TYPE); + contextv2c.setCommunity(community); + } + + // SNMP v3 + else if (snmpVersion == SNMP_V3) { + int authProtocolCode = 0; + int privacyProtocolCode = 0; + boolean authenticate = false; + boolean privacy = false; + + // Some sanity check with the "context" + if (contextEngineID == null) { contextEngineID = new byte[0]; } + if (contextName == null) { contextName = ""; } + + // Verify the username + if (authUsername == null) { authUsername = ""; } + + // Verify and translate the authentication type + if (authType == null || authUsername == null || authPassword == null) { + authenticate = false; + authProtocolCode = 4; + authPassword = ""; + } + else if (authType.isEmpty() || authUsername.isEmpty() || authPassword.isEmpty()) { + authenticate = false; + authProtocolCode = 4; + authPassword = ""; + } + else if (authType.equals(SNMP_AUTH_MD5)) { + authenticate = true; + authProtocolCode = SnmpContextv3Face.MD5_PROTOCOL; + } + else if (authType.equals(SNMP_AUTH_SHA)) { + authenticate = true; + authProtocolCode = SnmpContextv3Face.SHA1_PROTOCOL; + } + + // Verify the privacy thing + if (privacyType == null || privacyPassword == null) { + privacy = false; + } + else if (privacyType.isEmpty() || privacyPassword.isEmpty()) { + privacy = false; + } + else if (privacyType.equals(SNMP_PRIVACY_DES)) { + privacy = true; + privacyProtocolCode = SnmpContextv3Face.DES_ENCRYPT; + } + else if (privacyType.equals(SNMP_PRIVACY_AES)) { + privacy = true; + privacyProtocolCode = SnmpContextv3Face.AES_ENCRYPT; + } + + // Privacy with no authentication is impossible + if (privacy && !authenticate) { + throw new IllegalStateException("Authentication is required for privacy to be enforced"); + } + + // Create the context + contextv3 = new SnmpContextv3(host, port, SOCKET_TYPE); + contextv3.setContextEngineId(contextEngineID); + contextv3.setContextName(contextName); + contextv3.setUserName(authUsername); + contextv3.setUseAuthentication(authenticate); + if (authenticate) { + contextv3.setUserAuthenticationPassword(authPassword); + contextv3.setAuthenticationProtocol(authProtocolCode); + contextv3.setUsePrivacy(privacy); + if (privacy) { + contextv3.setPrivacyProtocol(privacyProtocolCode); + contextv3.setUserPrivacyPassword(privacyPassword); + } + } + } + + // SNMP v1 (default) + else { + contextv1 = new SnmpContext(host, port, SOCKET_TYPE); + contextv1.setCommunity(community); + } + + // Small thing: set the prefix for hex values (default is "0x" but we're setting it to empty) + AsnOctets.setHexPrefix(""); + + // AsnObject.setDebug(15); + + } + + /** + * Releases the resources associated to this instance + * (or so at least we believe...) + */ + public void freeResources() { + if (contextv1 != null) { contextv1.destroy(); contextv1 = null;} + if (contextv2c != null) { contextv2c.destroy(); contextv2c = null;} + if (contextv3 != null) { contextv3.destroy(); contextv3 = null;} + + if (pdu != null) { pdu = null; } + } + + + /** + * Create the PDU and sets the timeout + *

Note: This method has been created just to avoid duplicate code in the get, getNext and walk functions + */ + private void createPdu() { + // Create the PDU based on the proper context + if (snmpVersion == SNMP_V2C) { pdu = new BlockPdu(contextv2c); } + else if (snmpVersion == SNMP_V3) { pdu = new BlockPdu(contextv3); } + else { pdu = new BlockPdu(contextv1); } + + // Set the timeout + if (retryIntervals != null) { + pdu.setRetryIntervals(retryIntervals); + } + } + + + /** + * Perform a GET operation on the specified OID + * @param oid OID on which to perform a GET operation + * @return Value of the specified OID + * @throws Exception in case of any problem + */ + public String get(String oid) throws Exception { + createPdu(); + pdu.setPduType(BlockPdu.GET); + pdu.addOid(oid); + return sendRequest().value; + } + + /** + * Perform a GET operation on the specified OID and return the details of the result (including the type of the value) + * @param oid OID on which to perform a GET operation + * @return A string in the form of the OID, "string" and the value, separated by tabs (\t) + * @throws Exception in case of any problem + */ + public String getWithDetails(String oid) throws Exception { + createPdu(); + pdu.setPduType(BlockPdu.GET); + pdu.addOid(oid); + SnmpResult result = sendRequest(); + return result.oid + "\t" + result.type + "\t" + result.value; + } + + /** + * Perform a GETNEXT operation on the specified OID + * @param oid OID on which to perform a GETNEXT operation + * @return A string in the form of the OID, "string" and the value, separated by tabs (\t) + * @throws Exception in case of any problem + */ + public String getNext(String oid) throws Exception { + createPdu(); + pdu.setPduType(BlockPdu.GETNEXT); + pdu.addOid(oid); + SnmpResult result = sendRequest(); + return result.oid + "\t" + result.type + "\t" + result.value; + } + + /** + * Perform a WALK, i.e. a series of GETNEXT operations until we fall off the tree + * @param oid Root OID of the tree + * @return Result of the WALK operation, as a long String. Each pair of oid/value is separated with a linefeed (at least, for now!) + * @throws Exception + * @throws IllegalArgumentException for bad specified OIDs + */ + public String walk(String oid) throws Exception { + + StringBuilder walkResult = new StringBuilder(); + String currentOID; + SnmpResult getNextResult; + + // Sanity check? + if (oid == null) { + throw new IllegalArgumentException("Invalid SNMP Walk OID: null"); + } + if (oid.length() < 3) { + throw new IllegalArgumentException("Invalid SNMP Walk OID: \"" + oid + "\""); + } + + // Now, something special: + // In the walk loop below, we will catch any exception and break out of the loop + // if anything happens. At that point, we simply return what we have, i.e. just + // as if everything was okay. Doing so, we fail to report authentication problems. + // So, the code using this will think it's just okay, even though the QA team + // intentionally put bad credentials to verify the error message... See MATSYA-464. + // + // So, we're going to first run a getNext() for nothing, just so that + // this call will throw the proper exception in case of credentials problems. + getNext(oid); + + currentOID = oid; + do { + createPdu(); + pdu.setPduType(BlockPdu.GETNEXT); + pdu.addOid(currentOID); + try { + getNextResult = sendRequest(); + } + catch (Exception e) { + // Something wrong? Get out of the loop and return what we have + break; + } + + currentOID = getNextResult.oid; + if (!currentOID.startsWith(oid)) + { + // We're off the tree, so get out of the loop + break; + } + + // Append the result + walkResult.append(currentOID + "\t" + getNextResult.type + "\t" + getNextResult.value + "\n"); + + } while (walkResult.length() < 10 * 1048576); // 10 MB is the limit for the result of our WALK operation. Should be enough. + + // Remove the trailing \n (if any) + int resultLength = walkResult.length(); + if (resultLength > 0) { + return walkResult.substring(0, resultLength - 1); + } + + // If nothing, return an empty string + return ""; + } + + + /** + * Read the content of an SNMP table + * @param rootOID Root OID of the SNMP table + * @param selectColumnArray Array of numbers specifying the column numbers of the array to be read. Use "ID" for the row number. + * @return A semicolon-separated list of values + * @throws IllegalArgumentException when the specified arguments are wrong + * @throws Exception when the underlying SNMP API throws one + */ + public List> table(String rootOID, String[] selectColumnArray) throws Exception { + + // Sanity check + if (rootOID == null) { + throw new IllegalArgumentException("Invalid SNMP Table OID: null"); + } + if (rootOID.length() < 3) { + throw new IllegalArgumentException("Invalid SNMP Table OID: \"" + rootOID + "\""); + } + if (selectColumnArray == null) { + throw new IllegalArgumentException("Invalid SNMP Table column numbers: null"); + } + if (selectColumnArray.length < 1) { + throw new IllegalArgumentException("Invalid SNMP Table column numbers: none"); + } + + // First of all, retrieve the list of IDs in the table + // To do so, we need to see what is the first column number available (it may not be 1) + createPdu(); + pdu.setPduType(BlockPdu.GETNEXT); + pdu.addOid(rootOID); + String firstValueOid = sendRequest().oid; + if (firstValueOid.isEmpty() || !firstValueOid.startsWith(rootOID)) { + // Empty table + return new ArrayList<>(); + } + + int tempIndex = firstValueOid.indexOf(".", rootOID.length() + 2); + if (tempIndex < 0) { + // Weird case, there is no "." after the rootOID in the OID of the first value we successfully got in the table + return new ArrayList<>(); + } + String firstColumnOid = firstValueOid.substring(0, tempIndex); + int firstColumnOidLength = firstColumnOid.length(); + + // Now, find the list of row IDs in this column. We're going to do something like a walk, except we don't care about the values. Just the OIDs. + ArrayList IDArray = new ArrayList(0); + String currentOID = firstColumnOid; + SnmpResult getNextResult; + do { + // Get next until we get out of the tree + createPdu(); + pdu.setPduType(BlockPdu.GETNEXT); + pdu.addOid(currentOID); + getNextResult = sendRequest(); + + currentOID = getNextResult.oid; + + // Outside? Exit! + if (!currentOID.startsWith(firstColumnOid)) + { + break; + } + + // Add the right part of the OID in the list of IDs (the part to the right of the column OID) + IDArray.add(currentOID.substring(firstColumnOidLength + 1)); + + } while (IDArray.size() < 10000); // Not more than 10000 lines, please... + + // And finally, build the result table + List> tableResult = new ArrayList<>(); + for (String ID : IDArray) { + // For each row... + List row = new ArrayList<>(); + for (String column : selectColumnArray) { + // For each column... + + // If the column has to provide the ID of the row + if (column.equals("ID")) { + row.add(ID); + } + else { + // Keep going, even in case of a failure + try { + row.add(get(rootOID + "." + column + "." + ID)); + } + catch (Exception e) { + row.add(""); + } + } + } + tableResult.add(row); + } + + // Return the result + return tableResult; + } + + + /** + * Sends the SNMP request and perform some minor interpretation of the result + * @return Result of the query in the form of a couple {oid;value} (SnmpResult) + * @throws PduException when an error happens at the SNMP layer + * @throws IOException when an error occurs at the network layer + * @throws Exception when we cannot get the value of the specified OID, because it does not exist + *

+ *

  • In case of no such OID, an exception is thrown. + *
  • In case of empty value, the result will have the oid and an empty value. + */ + private SnmpResult sendRequest() throws PduException, IOException, Exception { + + // Declarations + SnmpResult result = new SnmpResult(); + + // Send the SNMP request + varbind var = pdu.getResponseVariableBinding(); + + // Retrieve the OID and value of the response (a varbind) + AsnObjectId oid = var.getOid(); + AsnObject value = var.getValue(); + + // No such OID? Throw an exception (this needs to be caught gracefully by other functions) + byte valueType = value.getRespType(); + if (valueType == SnmpConstants.SNMP_VAR_NOSUCHOBJECT || + valueType == SnmpConstants.SNMP_VAR_NOSUCHINSTANCE || + valueType == SnmpConstants.SNMP_VAR_ENDOFMIBVIEW) { + throw new Exception(value.getRespTypeString()); + } + + // Empty? + else if (valueType == SnmpConstants.ASN_NULL) { + result.oid = oid.toString(); + result.type = "null"; + } + + // ASN_OCTET_STRING? (special case, because it may need to be displayed as an hexadecimal string) + // Normally, the API should take care of that, but this is not the case for 0x00:00:00:00 values, which are displayed as empty values + else if (valueType == SnmpConstants.ASN_OCTET_STR) { + + result.oid = oid.toString(); + result.type = "ASN_OCTET_STR"; + + // Map the value to the specific AsnOctets sub-class + AsnOctets octetStringValue = (AsnOctets)value; + + // First, convert the value as a string, using toString(). + // AsnOctets.toString() will convert the value to a normal string (with ASCII chars) + // or to the hexadecimal version of it, like 0x00:30:31:32 when the "normal" string is + // not printable + String octetStringValuetoString = octetStringValue.toString(); + + // Then forcibly convert the value to its hexadecimal representation, but replace ':' with blank spaces, to match with what PATROL does + String octetStringValuetoHex = octetStringValue.toHex().replace(':', ' '); + + // So, if the toString() and the toHex() value have the same length, it means that toString() is actually returning + // the hexadecimal representation (yeah, there is no other way to retrieve that, the SNMP API does not tell us + // whether the value is printable or not) + // If the SNMP API judges that the value is not printable, then we will use the toHex() value, with ':' replaced with blank spaces. + // But there is another case: if the original value is just a series of 0x00 (nul) chars, the SNMP API converts that to an + // empty string, while we need to actually display 00 00 00 00... + // That's what we're doing in the code below + + // If octetStringValuetoString is empty while the original value's length was greater than 0, then we'll need to convert it to hexadecimal + if (octetStringValuetoString.isEmpty() && octetStringValue.getBytes().length > 0) { + result.value = octetStringValuetoHex; + } + else if (octetStringValuetoString.length() == octetStringValuetoHex.length()) { + result.value = octetStringValuetoHex; + } + else { + result.value = octetStringValuetoString; + } + } + + // Sets the result object + else { + result.oid = oid.toString(); + result.type = value.getRespTypeString(); + result.value = value.toString(); + } + + return result; + + } // end of sendRequest + + +}// end of class - SNMPClient diff --git a/src/main/java/org/sentrysoftware/snmp/client/SnmpResult.java b/src/main/java/org/sentrysoftware/snmp/client/SnmpResult.java new file mode 100644 index 0000000..be46745 --- /dev/null +++ b/src/main/java/org/sentrysoftware/snmp/client/SnmpResult.java @@ -0,0 +1,29 @@ +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +package org.sentrysoftware.snmp.client; + +public class SnmpResult { + public String oid = ""; + public String value = ""; + public String type = ""; +} \ No newline at end of file diff --git a/src/main/java/uk/co/westhawk/snmp/beans/AnnexModemStatusBean.java b/src/main/java/uk/co/westhawk/snmp/beans/AnnexModemStatusBean.java new file mode 100644 index 0000000..1958f90 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/AnnexModemStatusBean.java @@ -0,0 +1,815 @@ +// NAME +// $RCSfile: AnnexModemStatusBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.22 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; + +import javax.swing.tree.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean is written for + * + * Remote Annex 2000 + * access server. + *

    + * + *

    + * The server comes with the Xylogics specific MIBs, you can + * find them in the Annex software installation, I couldn't find them on + * the Web. I did not use them for this bean, however. + *

    + * + *

    + * This bean uses the + * CHARACTER-MIB + * and + * RS-232-MIB. + *

    + * + *

    + * This bean collects information about the modem status, + * connected to the server. + * It will only collect those modems (see charPortOperStatus) that are + * "up". It will then show if the modem is in use of not (see + * rs232InSigState). + *

    + * + *

    + * You can get the data via the getModemIndexes() and + * getPortStatus(Long index) methods. This way you can visualise + * the data yourself. + *

    + * + *

    + * You can also use the Swing JTree to visualise the modems. + * This bean implements the Swing TreeNode interface. + * The user has to set the setDefaultTreeModel, so this class can update all + * the nodes that are added, removed of changed. + * If this class is not the root of the JTree, you have to set + * the (TreeNode) parent of this class. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a TreeModelEvent the application/applet + * will be notified. + *

    + * + *

    + * We only have one Annex server, so I don't know how and if it + * works with more than 1. Please let us know if it doesn't work. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 1.22 $ $Date: 2006/03/23 14:54:09 $ + */ +public class AnnexModemStatusBean extends SNMPRunBean + implements Observer, TreeNode +{ + private static final String version_id = + "@(#)$Id: AnnexModemStatusBean.java,v 1.22 2006/03/23 14:54:09 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * A unique value for each character port. This perhaps + * corresponding to the same value of ifIndex when the + * character port is associated with a hardware port + * represented by an ifIndex. + * + *

    Syntax: INTEGER

    + * + * See the CHARACTER-MIB. + */ + public final static String charPortIndex = + "1.3.6.1.2.1.19.2.1.1"; + /** + * An administratively assigned name for the port, typically with + * some local significance. + * + *

    Syntax: DisplayString

    + * + * See CHARACTER-MIB. + */ + public final static String charPortName = + "1.3.6.1.2.1.19.2.1.2"; + + + /** + * The port's actual, operational state, independent + * of flow control. + *
      + *
    1. + * 'up' indicates able to function normally.
    2. + *
    3. + * 'down' indicates inability to function for administrative or + * operational reasons.
    4. + *
    5. + * 'maintenance' indicates a maintenance mode, exclusive of normal + * operation, such as running a test.
    6. + *
    7. + * 'absent' indicates that port hardware is not present.
    8. + *
    9. + * 'active' indicates up with a user present (e.g. logged in).
    10. + *
    + * + *

    + * 'up' and 'active' correspond to ifOperStatus (rfc2863.mib) 'up'. + * 'down' and 'absent' correspond to ifOperStatus 'down'. + * 'maintenance' corresponds to ifOperStatus 'test'. + *

    + * + *

    Syntax: INTEGER

    + * + * See CHARACTER-MIB + * and IF-MIB-MIB. + */ + public final static String charPortOperStatus = + "1.3.6.1.2.1.19.2.1.7"; + + /** + * The current signal state. + * + *

    Syntax: INTEGER

    + * + * See RS-232-MIB. + */ + public final static String rs232InSigState = + "1.3.6.1.2.1.10.33.5.1.3"; + + private final static int NR_PORT_OID = 3; + + /** charPortOperStatus up. */ + public final static int portUP = 1; + /** charPortOperStatus down. */ + public final static int portDOWN = 2; + /** charPortOperStatus maintenance. */ + public final static int portMAINTENANCE = 3; + /** charPortOperStatus absent. */ + public final static int portABSENT = 4; + /** charPortOperStatus active. */ + public final static int portACTIVE = 5; + + /** + * One of rs232InSigName values. If the dcd of rs232InSigState is + * on, that means that there is contact. + */ + public final static int DCD = 6; + + /** rs232InSigState none. */ + public final static int sigNONE = 1; + /** rs232InSigState on. */ + public final static int sigON = 2; + /** rs232InSigState off. */ + public final static int sigOFF = 3; + + public final static String [] sig_state = + { + "unknown", + "none", + "in use", + "not in use" + }; + + private GetNextPdu_vec pduGetNext; + private Hashtable modemIndexStatusHash; + private Hashtable modemHash; + + private TreeNode parent; + private DefaultTreeModel treeModel; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + private int deviceType = 0; + private int openCount = 0; + private int modemStatus = 0; + +/** + * The default constructor. + */ +public AnnexModemStatusBean() +{ + modemIndexStatusHash = new Hashtable(); + modemHash = new Hashtable(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public AnnexModemStatusBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public AnnexModemStatusBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indexes (as Integers) of the voice modems that are + * open. Only the open voice modems of the card are saved. + * + * Use getPortStatus() or getPortStatusString() to get the status + * of the modem. + * + * @see #getPortStatus + * @see #getPortStatusString + */ +public Enumeration getModemIndexes() +{ + return modemIndexStatusHash.keys(); +} + +/** + * Returns the number of voice modems in the table. + */ +public synchronized int getModemCount() +{ + return modemIndexStatusHash.size(); +} + +/** + * Returns the name of the port. + * + * @param index The index of the port + * @return The name + * + */ +public String getPortName(Long index) +{ + String name = ""; + Object obj = modemHash.get(index); + if (obj != null) + { + PortInfo pInfo = (PortInfo) obj; + name = pInfo.getName(); + } + return name; +} + +/** + * Returns the status of the modem as an int. + * + * @param index The index of the modem + * @return The status + * + * @see #getModemIndexes + */ +public int getPortStatus(Long index) +{ + int status = 0; + Object obj = modemIndexStatusHash.get(index); + if (obj != null) + { + status = ((Integer)obj).intValue(); + } + return status; +} + +/** + * Returns the String representation of the status of the modem. + * + * @param index The index of the modem + * @return The status + * + * @see #getModemIndexes + */ +public String getPortStatusString(Long index) +{ + int status = getPortStatus(index); + String str = sig_state[status]; + return str; +} + +/** + * Returns the children of the reciever as an Enumeration. + */ +public Enumeration children() +{ + return modemHash.elements(); +} + +/** + * Returns the number of children TreeNodes the receiver + * contains. + */ +public int getChildCount() +{ + int sz = modemHash.size(); + return sz; +} + +/** + * Returns the child TreeNode at index + * childIndex. + */ +public TreeNode getChildAt(int childIndex) +{ + TreeNode node = null; + if (childIndex < modemHash.size()) + { + Enumeration e = modemHash.elements(); + for (int i=0; i<=childIndex; i++) + { + node = (TreeNode) e.nextElement(); + } + } + return node; +} + +/** + * Returns the index of node in the receivers children. + * If the receiver does not contain node, -1 will be + * returned. + */ +public int getIndex(TreeNode node) +{ + int ret = -1; + if (modemHash.contains(node)) + { + boolean found = false; + Enumeration e = modemHash.elements(); + while (e.hasMoreElements() && !found) + { + TreeNode n = (TreeNode) e.nextElement(); + found = (n == node); + ret++; + } + } + return ret; +} + +/** + * Returns the parent TreeNode of the receiver. + */ +public TreeNode getParent() +{ + return parent; +} + +/** + * Returns true if the receiver allows children. + */ +public boolean getAllowsChildren() +{ + return true; +} + +/** + * Returns true if the receiver is a leaf. + */ +public boolean isLeaf() +{ + return false; +} +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + + pduGetNext = new GetNextPdu_vec(context, NR_PORT_OID); + pduGetNext.addObserver(this); + + pduGetNext.addOid(charPortIndex); + pduGetNext.addOid(charPortName); + pduGetNext.addOid(charPortOperStatus); + try + { + pduGetNext.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + */ +public void update(Observable obs, Object ov) +{ + boolean loopHasEnded = false; + + if (obs instanceof GetNextPdu_vec) + { + int portIndex, portStatus; + String portName; + + varbind [] var; + pduGetNext = (GetNextPdu_vec) obs; + + if (pduGetNext.isTimedOut() == false) + { + if (pduGetNext.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind []) ov; + if (var[0].getOid().toString().startsWith(charPortIndex)) + { + portIndex = ((AsnInteger) var[0].getValue()).getValue(); + portName = ((AsnOctets) var[1].getValue()).getValue(); + portStatus = ((AsnInteger) var[2].getValue()).getValue(); + + Long indexInt = new Long(portIndex); + if (portStatus == portUP) + { + // I've found a port that has status up + // Store it for later use. + + PortInfo pStatus = + (PortInfo) modemHash.get(indexInt); + + if (pStatus == null) + { + pStatus = new PortInfo(portIndex, portName, this); + modemHash.put(indexInt, pStatus); + } + + // Now I have to find out its sigState + String oid = rs232InSigState + "." + String.valueOf(portIndex) + + "." + String.valueOf(DCD); + + try + { + GetPdu pduGet = new GetPdu(context); + pduGet.addOid(oid); + pduGet.addObserver(this); + pduGet.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // This port is not up, remove it from our info + + modemIndexStatusHash.remove(indexInt); + modemHash.remove(indexInt); + } + + // ask for the next modem + pduGetNext = new GetNextPdu_vec(context, NR_PORT_OID); + pduGetNext.addObserver(this); + + pduGetNext.addOid(var[0].getOid().toString()); + pduGetNext.addOid(var[1].getOid().toString()); + pduGetNext.addOid(var[2].getOid().toString()); + try + { + pduGetNext.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + loopHasEnded = true; + } + } + else + { + // Actually the loop is ended when + // we have all the responses from pduGet's. Since I + // cannot control that, I do it this way. + + loopHasEnded = true; + } + } + else + { + modemIndexStatusHash.clear(); + modemHash.clear(); + loopHasEnded = true; + } + } + else if (obs instanceof GetPdu) + { + GetPdu pduGet = (GetPdu) obs; + if (pduGet.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + varbind var = (varbind) ov; + + AsnObjectId oid = var.getOid(); + int sigStatus = ((AsnInteger) var.getValue()).getValue(); + + // the index is the one-but-last element in the OID + int len = oid.getSize(); + long portIndex = oid.getElementAt(len-2); + + Long indexInt = new Long(portIndex); + modemIndexStatusHash.put(indexInt, + new Integer(sigStatus)); + + PortInfo pStatus = + (PortInfo) modemHash.get(indexInt); + + if (pStatus != null) + { + pStatus.setStatus(sigStatus); + } + } + } + + if (loopHasEnded) + { + lastUpdateDate = new Date(); + javax.swing.SwingUtilities.invokeLater(new TreeUpdate()); + isGetNextInFlight = false; + } + +} + +/** + * Sets the parent for this TreeNode. If the parent is not set, this + * class should be the root of the TreeModel. + */ +public void setParent (TreeNode p) +{ + parent = p; +} + +/** + * Sets the DefaultTreeModel for this TreeNode. The tree model is used + * for notifying when any of the nodes were added, removed or changed. + */ +public void setDefaultTreeModel (DefaultTreeModel model) +{ + treeModel = model; +} + +/** + * Fire the property event. + * + * @see + * DefaultTreeModel#nodeStructureChanged + */ +protected void fireTreeModelChanged() +{ + if (treeModel != null) + { + treeModel.nodeStructureChanged(this); + } +} + +class PortInfo extends Object implements TreeNode +{ + private TreeNode parent; + private int portIndex, sigStatus; + private String portName; + +public PortInfo(int ind, String nm, TreeNode par) +{ + this(ind, 0, nm, par); +} + +public PortInfo(int ind, int st, String nm, TreeNode par) +{ + portIndex = ind; + sigStatus = st; + portName = nm; + parent = par; +} + +public int getIndex() +{ + return portIndex; +} + +public int getStatus() +{ + return sigStatus; +} + +public void setStatus(int st) +{ + sigStatus = st; +} + +public String getName() +{ + return portName; +} + +public String toString() +{ + return ""+portIndex + " " + portName + " " + sig_state[sigStatus]; +} + +/** + * Returns the children of the reciever as an Enumeration. + */ +public Enumeration children() +{ + return null; +} + +/** + * Returns the number of children TreeNodes the receiver + * contains. + */ +public int getChildCount() +{ + return 0; +} + +/** + * Returns the child TreeNode at index + * childIndex. + */ +public TreeNode getChildAt(int childIndex) +{ + return null; +} + +/** + * Returns the index of node in the receivers children. + * If the receiver does not contain node, -1 will be + * returned. + */ +public int getIndex(TreeNode node) +{ + return -1; +} + +/** + * Returns the parent TreeNode of the receiver. + */ +public TreeNode getParent() +{ + return parent; +} + +/** + * Returns true if the receiver allows children. + */ +public boolean getAllowsChildren() +{ + return true; +} + +/** + * Returns true if the receiver is a leaf. + */ +public boolean isLeaf() +{ + return true; +} + +} // end class PortInfo + +class TreeUpdate implements Runnable +{ + public void run() + { + fireTreeModelChanged(); + firePropertyChange("modems", null, null); + } +} + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/beans/AscendActiveSessionBean.java b/src/main/java/uk/co/westhawk/snmp/beans/AscendActiveSessionBean.java new file mode 100644 index 0000000..6d64d79 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/AscendActiveSessionBean.java @@ -0,0 +1,378 @@ +// NAME +// $RCSfile: AscendActiveSessionBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:55 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean is written for the Ascend Router from + * Lucent Technologies, Inc. + * + * The Ascend Enterprise MIBs can be downloaded from + * ByteSphere. + *

    + * + *

    + * This bean collects information about the active session on an Ascend router. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:55 $ + * + */ +public class AscendActiveSessionBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: AscendActiveSessionBean.java,v 1.13 2006/01/25 18:08:55 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * A unique number identifying this active session. + * See the session.mib + */ + public final static String ssnActiveCallReferenceNum = + "1.3.6.1.4.1.529.12.3.1.1"; + /** + * The name of the remote user. + * See the session.mib + */ + public final static String ssnActiveUserName = + "1.3.6.1.4.1.529.12.3.1.4"; + /** + * The IP address of the remote user. + * See the session.mib + */ + public final static String ssnActiveUserIPAddress = + "1.3.6.1.4.1.529.12.3.1.5"; + /** + * The subnet mask of the remote user. + * See the session.mib + */ + public final static String ssnActiveUserSubnetMask = + "1.3.6.1.4.1.529.12.3.1.6"; + /** + * The current service provided to the remote user. + * See the session.mib + */ + public final static String ssnActiveCurrentService = + "1.3.6.1.4.1.529.12.3.1.7"; + + private final static int NR_OID = 5; + + private final static int none = 1; + private final static int other = 2; // none of the following + private final static int ppp = 3; // Point-To-Point Protocol + private final static int slip = 4; // Serial Line IP + private final static int mpp = 5; // Multichannel PPP + private final static int x25 = 6; // X.25 + private final static int combinet = 7; // Combinet + private final static int frameRelay = 8; // Frame Relay + private final static int euraw = 9; + private final static int euui = 10; + private final static int telnet = 11; // telnet + private final static int telnetBinary = 12; // binary telnet + private final static int rawTcp = 13; // raw TCP + private final static int terminalServer = 14; // terminal server + private final static int mp = 15; // Multilink PPP + private final static int virtualConnect = 16; // Virtual Connect to a modem + private final static int dchannelX25 = 17; // D Channel X.25 + private final static int dtpt = 18; // DTPT session to ZGR + + private final static String msg_service[] = + { + "", + "none", + "other", + "ppp", + "slip", + "mpp", + "x25", + "combinet", + "frameRelay", + "euraw", + "euui", + "telnet", + "telnetBinary", + "rawTcp", + "terminalServer", + "mp", + "virtualConnect", + "dchannelX25", + "dtpt" + }; + + private GetNextPdu_vec pdu; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + private int callReferenceNum = 0; + private String userName = ""; + private String userIPAddress = "0.0.0.0"; + private String userSubnetMask = "0.0.0.0"; + private String currentService = "none"; + +/** + * The default constructor. + */ +public AscendActiveSessionBean() +{ +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public AscendActiveSessionBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public AscendActiveSessionBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the name of the remote user of the Ascend active session. + * + * @return the name + */ +public String getUserName() +{ + return userName; +} + +/** + * Returns the IP address of the remote user of the Ascend active + * session. + * + * @return the IP address + */ +public String getUserIPAddress() +{ + return userIPAddress; +} + +/** + * Returns the subnet mask of the remote user of the Ascend active + * session. + * + * @return the subnet mask + */ +public String getUserSubnetMask() +{ + return userSubnetMask; +} + +/** + * Returns the current service provided to the remote user of the Ascend + * active session. + * + * @return the current service + */ +public String getCurrentService() +{ + return currentService; +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new GetNextPdu_vec(context, NR_OID); + pdu.addObserver(this); + + pdu.addOid(ssnActiveCallReferenceNum); + pdu.addOid(ssnActiveUserName); + pdu.addOid(ssnActiveUserIPAddress); + pdu.addOid(ssnActiveUserSubnetMask); + pdu.addOid(ssnActiveCurrentService); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + int service; + varbind [] var; + + pdu = (GetNextPdu_vec) obs; + + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind []) ov; + callReferenceNum = ((AsnInteger) var[0].getValue()).getValue(); + + if (callReferenceNum > 0) + { + userName = ((AsnOctets) var[1].getValue()).getValue(); + userIPAddress = ((AsnOctets) var[2].getValue()).getValue(); + userSubnetMask = ((AsnOctets) var[3].getValue()).getValue(); + + service = ((AsnInteger) var[4].getValue()).getValue(); + currentService = msg_service[service]; + } + + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("services", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/DialogChannelStatusBean.java b/src/main/java/uk/co/westhawk/snmp/beans/DialogChannelStatusBean.java new file mode 100644 index 0000000..2765f58 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/DialogChannelStatusBean.java @@ -0,0 +1,759 @@ +// NAME +// $RCSfile: DialogChannelStatusBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.18 $ +// CREATED +// $Date: 2006/02/02 15:49:39 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; + +import javax.swing.tree.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean is written for a Dialogic card. + * + * The Dialogic MIBs come with their + * BoardWatch + * package. You will have to fill in a form before downloading it. + * + *

    + * This bean collects information about the voice channel status of the + * Dialogic card. It will only collect those channels that are open. + *

    + * + *

    + * You can get the data via the getChannelIndexes() and + * getChannelStatus(Integer index) methods. This way you can visualise + * the data yourself. + *

    + * + *

    + * You can also use the Swing JTree to visualise the channels. + * This bean implements the Swing TreeNode interface. + * The user has to set the setDefaultTreeModel, so this class can update all + * the nodes that are added, removed of changed. + * If this class is not the root of the JTree, you have to set + * the (TreeNode) parent of this class. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a TreeModelEvent the application/applet + * will be notified. + *

    + * + *

    + * We only have one (1) Dialogics card, so I don't know how and if it + * works with more than 1 card. Please let us know if it doesn't work. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 1.18 $ $Date: 2006/02/02 15:49:39 $ + * + */ +public class DialogChannelStatusBean extends SNMPRunBean + implements Observer, TreeNode +{ + private static final String version_id = + "@(#)$Id: DialogChannelStatusBean.java,v 1.18 2006/02/02 15:49:39 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * A unique value for each R4 device contained by the + * host. The value for each R4 device must remain + * constant at least from one re-initialization of the + * agent to the next re-initialization. + * + * See the dlgr4dev.mib. + */ + public final static String dlgR4DeviceIndex = + "1.3.6.1.4.1.3028.2.1.1.2.1.1.1"; + + /** + * Release 4 Device Name. This is the name the application will + * use when opening the device (e.g. dxxxB1C1, dtiB1T1, msiB1C1) + * See the dlgr4dev.mib. + */ + public final static String dlgR4DeviceName = + "1.3.6.1.4.1.3028.2.1.1.2.1.1.2"; + + /** + * An indication of the type of the device. + *
      + *
    1. + * other - some other type of device unknown to the agent.
    2. + *
    3. + * voice - A voice channel device. An entry exits in the + * dlgR4VoiceTable for this device.
    4. + *
    5. + * dti - A DTI timeslot device. An entry exits in the + * dlgR4DTITable for this device.
    6. + *
    7. + * isdn - An ISDN B-Channel device. An entry exits in the + * dlgR4ISDNTable for this device.
    8. + *
    9. + * msi - An MSI station set device. An entry exits in the + * dlgR4MSITable for this device.
    10. + *
    + * + * See the dlgr4dev.mib. + */ + public final static String dlgR4DeviceType = + "1.3.6.1.4.1.3028.2.1.1.2.1.1.3"; + + /** + * An indication of how many instances of this device is currently + * opened. + * See the dlgr4dev.mib. + */ + public final static String dlgR4DeviceOpenCount = + "1.3.6.1.4.1.3028.2.1.1.2.1.1.5"; + + /** + * Indicates current activity status on the (voice) channel. + * See the dlgr4dev.mib. + */ + public final static String dlgR4VoiceChannelStatus = + "1.3.6.1.4.1.3028.2.1.1.2.2.1.2"; + + private final static int NR_OID = 5; + + // dlgR4DeviceType values + public final static int unknown = 1; + public final static int voice = 2; + public final static int dti = 3; + public final static int isdn = 4; + public final static int msi = 5; + + // dlgR4VoiceChannelStatus values + public final static int idle = 1; + public final static int playing = 2; + public final static int recording = 3; + public final static int gettingDigits = 5; + public final static int blocked = 16; + + public final static int dialing = 4; + public final static int playTone = 6; + public final static int sendingFax = 8; + public final static int receivingFax = 9; + public final static int betweenFAXPages = 10; + public final static int hookState = 11; + public final static int winking = 12; + public final static int callProgess = 13; + public final static int gettingR2MF = 14; + + public final static String vch_status[] = + { + "", + "Channel not active", + "Playing Audio Data", + "Recording Audio Data", + "Dialing Digits", + "Collecting DTMF digits", + "Playing a tone", + "", + "Sending a FAX (VFX boards)", + "Receiving a FAX (VFX boards)", + "Between FAX pages (VFX boards)", + "Changing hook status to onhook or offhook", + "Performing a wink", + "Performing Call progress analysis", + "Retrieving R2MF digits", + "", + "Blocked" + }; + + private GetNextPdu_vec pdu; + private Hashtable channelIndexStatusHash; + private Hashtable channelHash; + + private TreeNode parent; + private DefaultTreeModel treeModel; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + private int deviceType = 0; + private String deviceName = ""; + private int openCount = 0; + private int channelStatus = 0; + +/** + * The default constructor. + */ +public DialogChannelStatusBean() +{ + channelIndexStatusHash = new Hashtable(); + channelHash = new Hashtable(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public DialogChannelStatusBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public DialogChannelStatusBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indexes (as Integers) of the voice channels that are + * open. Only the open voice channels of the card are saved. + * + * Use getChannelStatus() or getChannelStatusString() to get the status + * of the channel. + * + * @see #getChannelStatus + * @see #getChannelStatusString + */ +public Enumeration getChannelIndexes() +{ + return channelIndexStatusHash.keys(); +} + +/** + * Returns the number of voice channels in the table. + */ +public synchronized int getChannelCount() +{ + return channelIndexStatusHash.size(); +} + +/** + * Returns the name of the channel. + * + * @param index The index of the channel + * @return The name + * + */ +public String getChannelName(Integer index) +{ + String name = ""; + Object obj = channelHash.get(index); + if (obj != null) + { + ChannelStatus chSt = (ChannelStatus) obj; + name = chSt.getName(); + } + return name; +} + +/** + * Returns the status of the channel as an int. + * + * @param index The index of the channel + * @return The status + * + * @see #getChannelIndexes + */ +public int getChannelStatus(Integer index) +{ + int status = 0; + Object obj = channelIndexStatusHash.get(index); + if (obj != null) + { + status = ((Integer)obj).intValue(); + } + return status; +} + +/** + * Returns the String representation of the status of the channel. + * + * @param index The index of the channel + * @return The status + * + * @see #getChannelIndexes + */ +public String getChannelStatusString(Integer index) +{ + int status = getChannelStatus(index); + String str = vch_status[status]; + return str; +} + +/** + * Returns the children of the reciever as an Enumeration. + */ +public Enumeration children() +{ + return channelHash.elements(); +} + +/** + * Returns the number of children TreeNodes the receiver + * contains. + */ +public int getChildCount() +{ + int sz = channelHash.size(); + return sz; +} + +/** + * Returns the child TreeNode at index + * childIndex. + */ +public TreeNode getChildAt(int childIndex) +{ + TreeNode node = null; + if (childIndex < channelHash.size()) + { + Enumeration e = channelHash.elements(); + for (int i=0; i<=childIndex; i++) + { + node = (TreeNode) e.nextElement(); + } + } + return node; +} + +/** + * Returns the index of node in the receivers children. + * If the receiver does not contain node, -1 will be + * returned. + */ +public int getIndex(TreeNode node) +{ + int ret = -1; + if (channelHash.contains(node)) + { + boolean found = false; + Enumeration e = channelHash.elements(); + while (e.hasMoreElements() && !found) + { + TreeNode n = (TreeNode) e.nextElement(); + found = (n == node); + ret++; + } + } + return ret; +} + +/** + * Returns the parent TreeNode of the receiver. + */ +public TreeNode getParent() +{ + return parent; +} + +/** + * Returns true if the receiver allows children. + */ +public boolean getAllowsChildren() +{ + return true; +} + +/** + * Returns true if the receiver is a leaf. + */ +public boolean isLeaf() +{ + return false; +} +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + + pdu = new GetNextPdu_vec(context, NR_OID); + pdu.addObserver(this); + + pdu.addOid(dlgR4DeviceIndex); + pdu.addOid(dlgR4DeviceName); + pdu.addOid(dlgR4DeviceType); + pdu.addOid(dlgR4DeviceOpenCount); + pdu.addOid(dlgR4VoiceChannelStatus); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + */ +public void update(Observable obs, Object ov) +{ + boolean hasEnded = false; + int index; + varbind [] var; + + pdu = (GetNextPdu_vec) obs; + + if (pdu.isTimedOut() == false) + { + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind []) ov; + if (var[0].getOid().toString().startsWith(dlgR4DeviceIndex)) + { + index = ((AsnInteger) var[0].getValue()).getValue(); + deviceName = ((AsnOctets) var[1].getValue()).getValue(); + deviceType = ((AsnInteger) var[2].getValue()).getValue(); + openCount = ((AsnInteger) var[3].getValue()).getValue(); + channelStatus = ((AsnInteger) var[4].getValue()).getValue(); + + if (deviceType == voice) + { + Integer indexInt = new Integer(index); + if (openCount == 0) + { + channelIndexStatusHash.remove(indexInt); + channelHash.remove(indexInt); + } + else + { + channelIndexStatusHash.put(indexInt, + new Integer(channelStatus)); + + ChannelStatus cStatus = + (ChannelStatus) channelHash.get(indexInt); + + if (cStatus == null) + { + cStatus = new ChannelStatus(index, channelStatus, + deviceName, this); + channelHash.put(indexInt, cStatus); + } + else + { + cStatus.setStatus(channelStatus); + } + } + } + + // ask for the next channel + pdu = new GetNextPdu_vec(context, NR_OID); + pdu.addObserver(this); + + pdu.addOid(var[0].getOid().toString()); + pdu.addOid(var[1].getOid().toString()); + pdu.addOid(var[2].getOid().toString()); + pdu.addOid(var[3].getOid().toString()); + pdu.addOid(var[4].getOid().toString()); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + hasEnded = true; + } + } + else + { + hasEnded = true; + } + } + else + { + channelIndexStatusHash.clear(); + channelHash.clear(); + hasEnded = true; + } + + if (hasEnded) + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + javax.swing.SwingUtilities.invokeLater(new TreeUpdate()); + isGetNextInFlight = false; + } +} + +/** + * Sets the parent for this TreeNode. If the parent is not set, this + * class should be the root of the TreeModel. + */ +public void setParent (TreeNode p) +{ + parent = p; +} + +/** + * Sets the DefaultTreeModel for this TreeNode. The tree model is used + * for notifying when any of the nodes were added, removed or changed. + */ +public void setDefaultTreeModel (DefaultTreeModel model) +{ + treeModel = model; +} + +/** + * Fire the property event. + * + * @see + * DefaultTreeModel#nodeStructureChanged + */ +protected void fireTreeModelChanged() +{ + if (treeModel != null) + { + treeModel.nodeStructureChanged(this); + } +} + +class ChannelStatus extends Object implements TreeNode +{ + private TreeNode parent; + private int index, status; + private String name; + +public ChannelStatus(int ind, int st, String nm, TreeNode par) +{ + index = ind; + status = st; + name = nm; + parent = par; +} + +public int getIndex() +{ + return index; +} + +public int getStatus() +{ + return status; +} + +public void setStatus(int st) +{ + status = st; +} + +public String getName() +{ + return name; +} + +public String toString() +{ + return ""+index + " " + name + " " + vch_status[status]; +} + +/** + * Returns the children of the reciever as an Enumeration. + */ +public Enumeration children() +{ + return null; +} + +/** + * Returns the number of children TreeNodes the receiver + * contains. + */ +public int getChildCount() +{ + return 0; +} + +/** + * Returns the child TreeNode at index + * childIndex. + */ +public TreeNode getChildAt(int childIndex) +{ + return null; +} + +/** + * Returns the index of node in the receivers children. + * If the receiver does not contain node, -1 will be + * returned. + */ +public int getIndex(TreeNode node) +{ + return -1; +} + +/** + * Returns the parent TreeNode of the receiver. + */ +public TreeNode getParent() +{ + return parent; +} + +/** + * Returns true if the receiver allows children. + */ +public boolean getAllowsChildren() +{ + return true; +} + +/** + * Returns true if the receiver is a leaf. + */ +public boolean isLeaf() +{ + return true; +} + +} // end class ChannelStatus + +class TreeUpdate implements Runnable +{ + public void run() + { + fireTreeModelChanged(); + firePropertyChange("modems", null, null); + } +} + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/beans/InterfaceIndexesBean.java b/src/main/java/uk/co/westhawk/snmp/beans/InterfaceIndexesBean.java new file mode 100644 index 0000000..0abdae3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/InterfaceIndexesBean.java @@ -0,0 +1,295 @@ +// NAME +// $RCSfile: InterfaceIndexesBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:55 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about the number of interfaces on a + * system and their index. + *

    + * + *

    + * The number is the number of network interfaces (regardless of + * their current state) present on this system. The number + * will remain the same untill the next time the SNMP server is + * restarted. The interfaces may go up and down while running. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see InterfaceGetNextPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:55 $ + * + */ +public class InterfaceIndexesBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: InterfaceIndexesBean.java,v 1.13 2006/01/25 18:08:55 birgit Exp $ Copyright Westhawk Ltd"; + + private InterfaceGetNextPdu pdu; + private Hashtable interfaceHash; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + +/** + * The default constructor. + */ +public InterfaceIndexesBean() +{ + interfaceHash = new Hashtable(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public InterfaceIndexesBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public InterfaceIndexesBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indexes (as Strings) of the current interfaces (the list + * of ifIndex). + */ +public Enumeration getInterfaceIndexes() +{ + return interfaceHash.keys(); +} + +/** + * Returns the indexes (as Strings) of the current interfaces (the list + * of ifIndex). + * + * @since 4_14 + */ +public Set getInterfaceIndexSet() +{ + return interfaceHash.keySet(); +} + +/** + * Returns the number of current interfaces. + */ +public synchronized int getInterfaceCount() +{ + return interfaceHash.size(); +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + interfaceHash.clear(); + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new InterfaceGetNextPdu(context); + pdu.addObserver(this); + pdu.addOids(null); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + InterfaceGetNextPdu prev; + String hashKey; + + pdu = (InterfaceGetNextPdu) obs; + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + hashKey = String.valueOf(pdu.getIfIndex()); + if ((prev = (InterfaceGetNextPdu)interfaceHash.get(hashKey)) != null) + { + pdu.getSpeed(prev); + } + + // update the hashtable with the new answer + interfaceHash.put(hashKey, pdu); + + // perform the GetNext on the just received answer + prev = pdu; + pdu = new InterfaceGetNextPdu(context); + pdu.addObserver(this); + pdu.addOids(prev); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("InterfaceIndexes", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/IsHostReachableBean.java b/src/main/java/uk/co/westhawk/snmp/beans/IsHostReachableBean.java new file mode 100644 index 0000000..325f537 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/IsHostReachableBean.java @@ -0,0 +1,317 @@ +// NAME +// $RCSfile: IsHostReachableBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.14 $ +// CREATED +// $Date: 2006/01/26 12:38:59 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean will determine whether the host+port is up, by sending an + * UpSincePdu. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see UpSincePdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.14 $ $Date: 2006/01/26 12:38:59 $ + * + */ +public class IsHostReachableBean extends SNMPBean implements Observer +{ + private static final String version_id = + "@(#)$Id: IsHostReachableBean.java,v 1.14 2006/01/26 12:38:59 birgit Exp $ Copyright Westhawk Ltd"; + + private UpSincePdu pdu; + + private Date upSince = null; + private boolean isReachable = false; + + private SimpleDateFormat dateFormat; + + +/** + * The default constructor. + */ +public IsHostReachableBean() +{ + dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz"); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public IsHostReachableBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public IsHostReachableBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date when the host went up. This might be null is no + * answer is received yet. + * @return the date + * + * @see SNMPBean#getMessage() + * @see #isReachable() + */ +public Date getUpSinceDate() +{ + return upSince; +} + +/** + * Answer is set according to the received SNMP response. + * @see #getUpSinceDate() + */ +protected void setUpSinceDate(Date d) +{ + upSince = d; +} + +/** + * Indicates whether the host + port is reachable. + * The host + port is reachable if a valid response is received from a + * UpSincePdu request. + * @return is the host + port + community name valid + * + * @see SNMPBean#getMessage() + * @see #getUpSinceDate() + */ +public boolean isReachable() +{ + return isReachable; +} + +/** + * The reachable property is set according to the succes of making + * a connection and the response of the SNMP request. + * This method will fire a Property Change Event. + * + * @see #isReachable() + * @see SNMPBean#addPropertyChangeListener + */ +protected void setReachable(boolean b) +{ + boolean old; + old = isReachable; + isReachable = b; + + firePropertyChange("Reachable", new Boolean (old), + new Boolean (isReachable)); +} + + +/** + * This method performs the request and wait for it. It is not + * recommended to use the waitForSelf option, preferred is the action() + * method. + * Use it if it is really necessary to wait. + * + * @see SnmpContext + * @see #action() + * @see Pdu#waitForSelf() + */ +public void waitForSelfAction() +throws PduException, IOException +{ + action(true); +} + +/** + * This method actually performs the request. All properties should be + * set before this method is called. + * + * This will create a new SnmpContext and send a UpSincePdu SNMP + * request. + * If the connection fails, the reachable property will be set to false. + * + * @see SnmpContext + */ +public void action() +throws PduException, IOException +{ + action(false); +} + +protected void action(boolean wait) +throws PduException, IOException +{ + if (host != null + && + host.length() > 0 + && + port > 0) + { + try + { + if (context != null) + { + context.destroy(); + } + context = new SnmpContext(host, port, bindAddr, socketType); + context.setCommunity(community); + setMessage("Connection to host " + host + + " is made succesfully"); + + if (wait == true) + { + pdu = new UpSincePdu(context, null); + if (pdu.waitForSelf()) + { + this.update((Observable) pdu, (Object) null); + } + else + { + setMessage("No SNMP Response from " + host); + } + } + else + { + pdu = new UpSincePdu(context, this); + } + } + catch (IOException exc) + { + setMessage("IOException: " + exc.getMessage()); + setReachable(false); + } + catch (RuntimeException exc) + { + setMessage("RuntimeException: " + exc.getMessage()); + setReachable(false); + } + } +} + +/** + * The update method according to the Observer interface, it will be + * called when the Pdu response is received. + * If there is no error it means that the host is reachable. If it is + * not reachable the message will contain the type of error, if it is + * reachable the message will say since when the host is up. + */ +public void update(Observable obs, Object ov) +{ + pdu = (UpSincePdu) obs; + + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + setUpSinceDate(pdu.getDate()); + setMessage("Host " + host + " is up since " + + dateFormat.format(getUpSinceDate())); + setReachable(true); + } + else + { + setUpSinceDate(null); + setMessage("SNMP Response: " + pdu.getErrorStatusString()); + setReachable(false); + } +} + + +/** + * Destroys the context. + * @since 4_14 + */ +public void freeResources() +{ + if (context != null) + { + context.destroy(); + context = null; + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/NTPrintQBean.java b/src/main/java/uk/co/westhawk/snmp/beans/NTPrintQBean.java new file mode 100644 index 0000000..e95f189 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/NTPrintQBean.java @@ -0,0 +1,334 @@ +// NAME +// $RCSfile: NTPrintQBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:55 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects the names of the print queues installed on + * a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:55 $ + * + */ +public class NTPrintQBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: NTPrintQBean.java,v 1.13 2006/01/25 18:08:55 birgit Exp $ Copyright Westhawk Ltd"; + + public final static String svPrintQName = + "1.3.6.1.4.1.77.1.2.29.1.1"; + + private int svPrintQName_len; + private GetNextPdu pdu; + private Hashtable printHash; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + +/** + * The default constructor. + */ +public NTPrintQBean() +{ + printHash = new Hashtable(); + svPrintQName_len = svPrintQName.length(); +} + + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public NTPrintQBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public NTPrintQBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indices of the NT print queues. + * The OID of this print queue is a concatenation of the + * name (svPrintQName) OID and the print queue specific index. + * The index should be used to get the other properties of this print queue. + * + * @see #getIndex(String) + * @see #svPrintQName + */ +public Enumeration getIndices() +{ + return printHash.elements(); +} + +/** + * Returns the index of one of the print queues. + * The OID of this print + * queue is a concatenation of the name (svPrintQName) OID and the print + * queue specific index. + * The index should be used to get the other properties of this print queue. + * + * @param name The name of the print queue + * @return the print queue index, might be null if no print queue with such name + * exists + * @see #getIndices + * @see #getNames + */ +public String getIndex(String name) +{ + return (String) printHash.get(name); +} + +/** + * Returns the names of the NT print queues (the list + * of svPrintQName). + */ +public Enumeration getNames() +{ + return printHash.keys(); +} + +/** + * Returns the number of NT print queues. + */ +public synchronized int getCount() +{ + return printHash.size(); +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + printHash.clear(); + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(svPrintQName); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + varbind var; + String hashKey; + String oid, index, name; + + pdu = (GetNextPdu) obs; + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind) ov; + oid = ""; + if (var != null) + { + oid = var.getOid().toString(); + } + if (oid.startsWith(svPrintQName)) + { + // index is the part of the oid AFTER the svPrintQName + index = oid.substring(svPrintQName_len+1); + + name = ((AsnOctets) var.getValue()).getValue(); + + // update the hashtable with the new answer + printHash.put(name, index); + + // perform the GetNext on the just received answer + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(oid); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("resourceNames", null, null); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("resourceNames", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/NTServiceNamesBean.java b/src/main/java/uk/co/westhawk/snmp/beans/NTServiceNamesBean.java new file mode 100644 index 0000000..85f59b7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/NTServiceNamesBean.java @@ -0,0 +1,332 @@ +// NAME +// $RCSfile: NTServiceNamesBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects the names of the network services installed on + * a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + * + */ +public class NTServiceNamesBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: NTServiceNamesBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + public final static String svSvcName = "1.3.6.1.4.1.77.1.2.3.1.1"; + + private int svSvcName_len; + private GetNextPdu pdu; + private Hashtable serviceHash; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + +/** + * The default constructor. + */ +public NTServiceNamesBean() +{ + serviceHash = new Hashtable(); + svSvcName_len = svSvcName.length(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public NTServiceNamesBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public NTServiceNamesBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indices of the NT network services. + * The OID of this network service is a concatenation of the + * name (svSvcName) OID and the network service specific index. + * The index should be used to get the other properties of this service. + * + * @see #getIndex(String) + * @see #svSvcName + */ +public Enumeration getIndices() +{ + return serviceHash.elements(); +} + +/** + * Returns the index of one of the services. + * The OID of this network service is a concatenation of the + * name (svSvcName) OID and the network service specific index. + * The index should be used to get the other properties of this service. + * + * @param name The name of the service + * @return the service index, might be null if no service with such name + * exists + * @see #getIndices + * @see #getNames + */ +public String getIndex(String name) +{ + String ret = null; + if (name != null) + { + ret = (String) serviceHash.get(name); + } + return ret; +} + +/** + * Returns the names of the NT network services (the list + * of svSvcName). + */ +public Enumeration getNames() +{ + return serviceHash.keys(); +} + +/** + * Returns the number of NT network services. + */ +public synchronized int getCount() +{ + return serviceHash.size(); +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + serviceHash.clear(); + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(svSvcName); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + varbind var; + String hashKey; + String oid, index, name; + + pdu = (GetNextPdu) obs; + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind) ov; + oid = var.getOid().toString(); + if (oid.startsWith(svSvcName)) + { + // index is the part of the oid AFTER the svSvcName + index = oid.substring(svSvcName_len+1); + + name = ((AsnOctets) var.getValue()).getValue(); + + // update the hashtable with the new answer + serviceHash.put(name, index); + + // perform the GetNext on the just received answer + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(oid); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("serviceNames", null, null); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("serviceNames", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/NTSharedResBean.java b/src/main/java/uk/co/westhawk/snmp/beans/NTSharedResBean.java new file mode 100644 index 0000000..5baac9a --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/NTSharedResBean.java @@ -0,0 +1,335 @@ +// NAME +// $RCSfile: NTSharedResBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects the names of the shared resources installed on + * a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + * + */ +public class NTSharedResBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: NTSharedResBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + public final static String svShareName = "1.3.6.1.4.1.77.1.2.27.1.1"; + + private int svShareName_len; + private GetNextPdu pdu; + private Hashtable resourceHash; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + +/** + * The default constructor. + */ +public NTSharedResBean() +{ + resourceHash = new Hashtable(); + svShareName_len = svShareName.length(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public NTSharedResBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public NTSharedResBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indices of the NT shared resources. + * The OID of this shared resource is a concatenation of the + * name (svShareName) OID and the shared resource specific index. + * The index should be used to get the other properties of this resource. + * + * @see #getIndex(String) + * @see #svShareName + */ +public Enumeration getIndices() +{ + return resourceHash.elements(); +} + +/** + * Returns the index of one of the resources. + * The OID of this shared resource is a concatenation of the + * name (svShareName) OID and the shared resource specific index. + * The index should be used to get the other properties of this resource. + * + * @param name The name of the resource + * @return the resource index, might be null if no resource with such name + * exists + * @see #getIndices + * @see #getNames + */ +public String getIndex(String name) +{ + String ret = null; + if (name != null) + { + ret = (String) resourceHash.get(name); + } + return ret; +} + +/** + * Returns the names of the NT shared resources (the list + * of svShareName). + */ +public Enumeration getNames() +{ + return resourceHash.keys(); +} + +/** + * Returns the number of NT shared resources. + */ +public synchronized int getCount() +{ + return resourceHash.size(); +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + * + * @see SNMPBean#action + */ +public void action() +{ + if (isHostPortReachable()) + { + resourceHash.clear(); + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(svShareName); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + varbind var; + String hashKey; + String oid, index, name; + + pdu = (GetNextPdu) obs; + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind) ov; + oid = var.getOid().toString(); + if (oid.startsWith(svShareName)) + { + // index is the part of the oid AFTER the svShareName + index = oid.substring(svShareName_len+1); + + name = ((AsnOctets) var.getValue()).getValue(); + + // update the hashtable with the new answer + resourceHash.put(name, index); + + // perform the GetNext on the just received answer + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(oid); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("resourceNames", null, null); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("resourceNames", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/NTUserNamesBean.java b/src/main/java/uk/co/westhawk/snmp/beans/NTUserNamesBean.java new file mode 100644 index 0000000..8ab5f10 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/NTUserNamesBean.java @@ -0,0 +1,327 @@ +// NAME +// $RCSfile: NTUserNamesBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects the names of the network users installed on + * a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetNextPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + * + */ +public class NTUserNamesBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: NTUserNamesBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + public final static String svUserName = "1.3.6.1.4.1.77.1.2.25.1.1"; + + private int svUserName_len; + private GetNextPdu pdu; + private Hashtable userHash; + + private boolean isGetNextInFlight; + private Date lastUpdateDate = null; + + +/** + * The default constructor. + */ +public NTUserNamesBean() +{ + userHash = new Hashtable(); + svUserName_len = svUserName.length(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public NTUserNamesBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public NTUserNamesBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * Returns the indices of the NT network users. + * The OID of this network user is a concatenation of the + * name (svUserName) OID and the network user specific index. + * The index should be used to get the other properties of this user. + * + * @see #getIndex(String) + * @see #svUserName + */ +public Enumeration getIndices() +{ + return userHash.elements(); +} + +/** + * Returns the index of one of the users. + * The OID of this network user is a concatenation of the + * name (svUserName) OID and the network user specific index. + * The index should be used to get the other properties of this user. + * + * @param name The name of the user + * @return the user index, might be null if no user with such name + * exists + * @see #getIndices + * @see #getNames + */ +public String getIndex(String name) +{ + return (String) userHash.get(name); +} + +/** + * Returns the names of the NT network users (the list + * of svUserName). + */ +public Enumeration getNames() +{ + return userHash.keys(); +} + +/** + * Returns the number of NT network users. + */ +public synchronized int getCount() +{ + return userHash.size(); +} + +/** + * This method starts the action of the bean. It will initialises + * all variables before starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + userHash.clear(); + lastUpdateDate = new Date(); + isGetNextInFlight = false; + setRunning(true); + } +} + +/** + * Implements the running of the bean. + * + * It will send the Pdu, if the previous one is not still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isGetNextInFlight == false) + { + // start the GetNext loop again + isGetNextInFlight = true; + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(svUserName); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * This method is called when the Pdu response is received. When all + * answers are received it will fire the property change event. + * + * The answers are stored in a hashtable, this is done because the speed + * can only be calculated with the previous answer. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + varbind var; + String hashKey; + String oid, index, name; + + pdu = (GetNextPdu) obs; + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind) ov; + oid = var.getOid().toString(); + if (oid.startsWith(svUserName)) + { + // index is the part of the oid AFTER the svUserName + index = oid.substring(svUserName_len+1); + + name = ((AsnOctets) var.getValue()).getValue(); + + // update the hashtable with the new answer + userHash.put(name, index); + + // perform the GetNext on the just received answer + pdu = new GetNextPdu(context); + pdu.addObserver(this); + pdu.addOid(oid); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("userNames", null, null); + } + } + else + { + // the GetNext loop has ended + lastUpdateDate = new Date(); + isGetNextInFlight = false; + firePropertyChange("userNames", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/NcdPerfDataBean.java b/src/main/java/uk/co/westhawk/snmp/beans/NcdPerfDataBean.java new file mode 100644 index 0000000..deb21a3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/NcdPerfDataBean.java @@ -0,0 +1,897 @@ +// NAME +// $RCSfile: NcdPerfDataBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.12 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about a + * IBM Network Computer. + *

    + * + *

    + * It provide the following data: + *

    + *
      + *
    • the speed of the Ethernet Card
    • + *
    • the available memory in bytes
    • + *
    • the name of the user that is logged in
    • + *
    + * + *

    + * A message will be set if some of the data is not available + *

    + * + *

    + * This class uses the NCDware v3.2 MIB, which was very kindly provided + * to me by Network Computing Devices, inc + * (NCD). This MIB is an extention of the older versions of the + * MIB + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see #setUpdateInterval(int) + * @see #setUpdateInterval(String) + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * + * @author Birgit Arkesteijn + * @version $Revision: 1.12 $ $Date: 2006/01/17 17:43:53 $ + */ +public class NcdPerfDataBean extends SNMPBean + implements PropertyChangeListener +{ + private static final String version_id = + "@(#)$Id: NcdPerfDataBean.java,v 1.12 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * Used as propertyName when a propertyChangeEvent is fired because + * the speed was updated + */ + public final static String speedPropertyName = "Speed"; + + /** + * Used as propertyName when a propertyChangeEvent is fired because + * the memory was updated + */ + public final static String memoryPropertyName = "Memory"; + + /** + * Used as propertyName when a propertyChangeEvent is fired because + * the user name was updated + */ + public final static String userPropertyName = "User"; + + /** + * Used as propertyName when a propertyChangeEvent is fired because + * a message was set + */ + public final static String messagePropertyName = "Message"; + + /** + * Used as name when no one is logged in. + */ + public final static String noLogin = "no one is logged in"; + + /** + * Used as name when the name is not available. + */ + public final static String noName = "not available"; + + + private ethernet ethernetData; + private user userData; + private memory memoryData; + + private Date lastUpdateDate = null; + + private int interval = 3000; + private long speed = -1; + private long memoryAvail = -1; + private String userName = ""; + +/** + * The default constructor. + */ +public NcdPerfDataBean() +{ +} + +/** + * Returns the speed (bits per second) of the ethernet card interface. + * @return the speed (b/s) + */ +public long getSpeed() +{ + return speed; +} + +/** + * Returns the amount of RAM memory in bytes which is + * currently available. + * + * @return the memory in bytes + */ +public long getMemory() +{ + return memoryAvail; +} + +/** + * Returns the login name of the user that is logged in. + * + * @return the user name + * @see #noLogin + * @see #noName + */ +public String getUserName() +{ + return userName; +} + +/** + * Returns the update interval. This is the interval that the + * bean will sleep between 2 requests. + * + * @return the update interval in msec + * @see #setUpdateInterval(int) + * @see #setUpdateInterval(String) + */ +public int getUpdateInterval() +{ + return interval; +} + +/** + * Sets the update interval. This is the interval that the + * bean will sleep between 2 requests. + * The default will be 3000 (= 3 sec). + * + * @param i the interval in msec + * @see #getUpdateInterval + * @see #setUpdateInterval(String) + */ +public void setUpdateInterval(int i) +{ + if (interval != i) + { + interval = i; + } +} + +/** + * Sets the update interval as String. + * + * @param i the interval in msec as String + * @see #getUpdateInterval + * @see #setUpdateInterval(int) + */ +public void setUpdateInterval(String i) +{ + int iNo; + try + { + iNo = Integer.valueOf(i.trim()).intValue(); + setUpdateInterval(iNo); + } + catch (NumberFormatException exp) + { + } +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * This method starts sending the SNMP request. All properties should be + * set before this method is called. + * + * The actual sending will take place in the run method. + * It makes a new snmp context and initialises all variables before + * starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + + if (ethernetData != null) + { + ethernetData.setRunning(false); + } + if (userData != null) + { + userData.setRunning(false); + } + if (memoryData != null) + { + memoryData.setRunning(false); + } + ethernetData = new ethernet(host, port, community, interval, context); + userData = new user(host, port, community, interval, context); + memoryData = new memory(host, port, community, interval, context); + + ethernetData.addPropertyChangeListener(this); + userData.addPropertyChangeListener(this); + memoryData.addPropertyChangeListener(this); + } +} + +protected void setMessage(String st) +{ + message = st; + firePropertyChange (NcdPerfDataBean.messagePropertyName, + null, message); +} + +/** + * This method is called when a new value of the speed, memory, user or + * message is available. It will propagate this event to any listeners. + * + * @see #speedPropertyName + * @see #memoryPropertyName + * @see #userPropertyName + * @see #messagePropertyName + */ +public void propertyChange(PropertyChangeEvent e) +{ + Object src = e.getSource(); + Object oldV = e.getOldValue(); + Object newV= e.getNewValue(); + String propName = e.getPropertyName(); + + if (propName.equals(messagePropertyName)) + { + setMessage((String) newV); + } + else + { + if (src == ethernetData) + { + speed = ((Long) newV).longValue(); + } + else if (src == userData) + { + userName = (String) newV; + } + else if (src == memoryData) + { + memoryAvail = ((Long) newV).longValue(); + } + + firePropertyChange (e.getPropertyName(), oldV, newV); + } +} + +} + + +/** + *

    + * This class is the super class of the classes ethernet, user and + * memory. + *

    + * + * @see user + * @see ethernet + * @see memory + */ +abstract class ncdPart extends SNMPRunBean +{ + Thread me; + protected boolean isPduInFlight; + +public abstract void doPdu() +throws PduException, IOException; + +public ncdPart (String h, int p, String c, int i, SnmpContext con) +{ + // reuse the context of the NcdPrefData class, so do not call + // isHostPortReachable() ! + context = con; + setHost(h); + setPort(p); + setCommunityName(c); + setUpdateInterval(i); + + action(); +} + +protected void setMessage(String st) +{ + message = st; + firePropertyChange (NcdPerfDataBean.messagePropertyName, + null, message); +} + +public void action() +{ + setRunning(true); +} + +/** + * + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isPduInFlight == false) + { + isPduInFlight = true; + try + { + doPdu(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +} + +/** + *

    + * This class collects information about the ethernet card. + *

    + * + *

    + * The first time it will search the interface table to find the entry + * describing the ethernet card. After it has been found, it will ask + * for the information to calculate the speed. + *

    + * + *

    + * If the ethernet card is not found, this class assumes that it is not + * available at all, and will not try again. + *

    + * + * @see user + * @see memory + */ +class ethernet extends ncdPart implements Observer +{ + private final static int ethernetType = 6; + private final static int statusUp = 1; + + private final static String sysUpTime = "1.3.6.1.2.1.1.3.0"; + private final static String ifIndex = "1.3.6.1.2.1.2.2.1.1"; + private final static String ifType = "1.3.6.1.2.1.2.2.1.3"; + private final static String ifOperStatus = "1.3.6.1.2.1.2.2.1.8"; + private final static String ifInOctets = "1.3.6.1.2.1.2.2.1.10"; + private final static String ifOutOctets = "1.3.6.1.2.1.2.2.1.16"; + + private long speed = -1; + private long prevSpeed = -1; + private long prevSys = -1; + private int prevOper = -1; + private long prevInO = -1; + private long prevOutO = -1; + private int index = -1; + + GetNextPdu_vec typePdu; + GetPdu_vec ethernetPdu; + + private boolean first = true; + private boolean foundEthernet = false; + +public ethernet (String h, int p, String c, int i, SnmpContext con) +{ + super(h, p, c, i, con); + first = true; + foundEthernet = false; + + speed = -1; + prevSpeed = -1; + prevSys = -1; + prevOper = -1; + prevInO = -1; + prevOutO = -1; +} + +public long getSpeed() +{ + return speed; +} + +public void doPdu() throws PduException, IOException +{ + if (first) + { + // first go looking which interface is the ethernet one + typePdu = new GetNextPdu_vec(context, 2); + typePdu.addObserver(this); + typePdu.addOid(ifIndex); + typePdu.addOid(ifType); + typePdu.send(); + + first = false; + } + else if (foundEthernet) + { + ethernetPdu = new GetPdu_vec(context, 5); + ethernetPdu.addObserver(this); + ethernetPdu.addOid(sysUpTime); + ethernetPdu.addOid(ifType + "." + index); + ethernetPdu.addOid(ifOperStatus + "." + index); + ethernetPdu.addOid(ifInOctets + "." + index); + ethernetPdu.addOid(ifOutOctets + "." + index); + ethernetPdu.send(); + } +} + +public void update(Observable obs, Object ov) +{ + varbind [] vars; + + if (obs == typePdu) + { + if (typePdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + vars = (varbind[]) ov; + if (vars[0].getOid().toString().startsWith(ifIndex)) + { + int i = ((AsnInteger) vars[0].getValue()).getValue(); + int t = ((AsnInteger) vars[1].getValue()).getValue(); + + if (t == ethernetType) + { + // found it! + index = i; + foundEthernet = true; + isPduInFlight = false; + } + else + { + // not found it, ask for the next one + typePdu = new GetNextPdu_vec(context, 2); + typePdu.addObserver(this); + typePdu.addOid(vars[0]); + typePdu.addOid(vars[1]); + try + { + typePdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + } + else + { + setMessage("Ethernet interface not available!"); + } + } + else + { + setMessage("Ethernet interface not available!"); + } + } + else + { + speed = -1; + int oper = -1; + if (ethernetPdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + vars = (varbind[]) ov; + + long sys = ((AsnUnsInteger) vars[0].getValue()).getValue(); + int t = ((AsnInteger) vars[1].getValue()).getValue(); + oper = ((AsnInteger) vars[2].getValue()).getValue(); + long inO = ((AsnUnsInteger) vars[3].getValue()).getValue(); + long outO = ((AsnUnsInteger) vars[4].getValue()).getValue(); + + if (t == ethernetType) + { + if (oper == statusUp && prevOper == statusUp) + { + long tdif = (sys - prevSys); + if (tdif != 0) + { + speed = ((inO - prevInO) + (outO - prevOutO)) + / tdif * 100; + + firePropertyChange (NcdPerfDataBean.speedPropertyName, + new Long(prevSpeed), + new Long(speed)); + } + } + + prevSys = sys; + prevInO = inO; + prevOutO = outO; + } + else + { + // the index has changed, start searching again + first = true; + foundEthernet = false; + } + } + prevSpeed = speed; + prevOper = oper; + + isPduInFlight = false; + } +} + +} + +/** + *

    + * This class collects information about the user that is logged in. + *

    + * + *

    + * The first time it will search the NCD environment table to find the + * entry describing the environment variable USER. After it has been found, + * it will ask for the information to calculate the speed. + *

    + * + *

    + * When it cannot be found, it will try to see the difference between + * the situation where nobody is logged in and the situation where such + * information will never be avaible since it does not concern a NCD. + *

    + * + *

    + * It is not so easy as it may seem. If the machine is shut off, it seem + * if the machine is not a NCD. + *

    + * + * @see ethernet + * @see memory + */ +class user extends ncdPart implements Observer +{ + private final static String USER = "USER"; + + private final static String ncdPrefEnvVarTableIndex = + "1.3.6.1.4.1.82.2.3.15.54.1.1"; + private final static String ncdPrefEnvVarTableName = + "1.3.6.1.4.1.82.2.3.15.54.1.2"; + private final static String ncdPrefEnvVarTableValue = + "1.3.6.1.4.1.82.2.3.15.54.1.3"; + + private int index = -1; + private String name = ""; + private String prevName = ""; + + GetNextPdu_vec namePdu; + GetPdu_vec userPdu; + + private boolean first = true; + private boolean isNcd = false; + private boolean foundUser = false; + +public user (String h, int p, String c, int i, SnmpContext con) +{ + super(h, p, c, i, con); + first = true; + isNcd = false; + foundUser = false; + + userPdu = null; + name = ""; + prevName = ""; +} + +public String getUserName() +{ + return name; +} + +public void doPdu() throws PduException, IOException +{ + if (first + || + (isNcd && !foundUser)) + { + // first go looking which interface is the ethernet one + namePdu = new GetNextPdu_vec(context, 3); + namePdu.addObserver(this); + namePdu.addOid(ncdPrefEnvVarTableIndex); + namePdu.addOid(ncdPrefEnvVarTableName); + namePdu.addOid(ncdPrefEnvVarTableValue); + namePdu.send(); + + first = false; + } + else if (foundUser) + { + userPdu = new GetPdu_vec(context, 3); + userPdu.addObserver(this); + userPdu.addOid(ncdPrefEnvVarTableIndex + "." + index); + userPdu.addOid(ncdPrefEnvVarTableName + "." + index); + userPdu.addOid(ncdPrefEnvVarTableValue + "." + index); + userPdu.send(); + } +} + +public void update(Observable obs, Object ov) +{ + varbind [] vars; + + if (obs == namePdu) + { + + if (namePdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + vars = (varbind[]) ov; + if (vars[0].getOid().toString().startsWith(ncdPrefEnvVarTableIndex)) + { + // as soon as one response concerns the NCD environment + // table, I assume it concerns a NCD machine. + isNcd = true; + + int i = ((AsnInteger) vars[0].getValue()).getValue(); + String n = ((AsnOctets) vars[1].getValue()).getValue(); + String v = ""; + if (vars[2].getValue() instanceof AsnOctets) + { + v = ((AsnOctets) vars[2].getValue()).getValue(); + } + + if (n.equals(USER)) + { + // found it! + index = i; + foundUser = true; + name = v; + isPduInFlight = false; + } + else + { + // not found it, ask for the next one + namePdu = new GetNextPdu_vec(context, 3); + namePdu.addObserver(this); + namePdu.addOid(vars[0]); + namePdu.addOid(vars[1]); + namePdu.addOid(vars[2]); + try + { + namePdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + } + else + { + if (isNcd) + { + name = NcdPerfDataBean.noLogin; + } + else + { + name = NcdPerfDataBean.noName; + } + if (!name.equals(prevName)) + { + firePropertyChange (NcdPerfDataBean.userPropertyName, + prevName, name); + } + + prevName = name; + isPduInFlight = false; + } + } + else + { + prevName = name; + isPduInFlight = false; + } + } + else + { + name = ""; + if (userPdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + vars = (varbind[]) ov; + + int i = ((AsnInteger) vars[0].getValue()).getValue(); + String n = ((AsnOctets) vars[1].getValue()).getValue(); + String v = ""; + if (vars[2].getValue() instanceof AsnOctets) + { + v = ((AsnOctets) vars[2].getValue()).getValue(); + } + + + name = v; + if (!name.equals(prevName)) + { + firePropertyChange (NcdPerfDataBean.userPropertyName, + prevName, name); + } + + } + else + { + first = true; + isNcd = true; + foundUser = false; + } + + prevName = name; + isPduInFlight = false; + } +} + +} + +/** + *

    + * This class collects information about the available memory. + *

    + * + *

    + * If this information is not available, probably because it is not a + * NCD machine, this class will not try again. + *

    + * + * @see ethernet + * @see user + */ +class memory extends ncdPart implements Observer +{ + private final static String ncdSysMemAvail = + "1.3.6.1.4.1.82.2.1.1.2.0"; + + GetPdu memoryPdu; + private long memory = -1; + private long prevMemory = -1; + + private boolean first = true; + private boolean isAvailable = false; + +public memory (String h, int p, String c, int i, SnmpContext con) +{ + super(h, p, c, i, con); + + first = true; + isAvailable = false; +} + +public long getMemory() +{ + return memory; +} + +public void doPdu() throws PduException, IOException +{ + if (first || isAvailable) + { + memoryPdu = new GetPdu(context); + memoryPdu.addOid(ncdSysMemAvail); + memoryPdu.addObserver(this); + first = false; + } +} + +public void update(Observable obs, Object ov) +{ + varbind var; + + memory = -1; + if (memoryPdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + var = (varbind) ov; + + memory = ((AsnUnsInteger) var.getValue()).getValue(); + + firePropertyChange (NcdPerfDataBean.memoryPropertyName, + new Long(prevMemory), + new Long(memory)); + + isAvailable = true; + } + else + { + setMessage("Memory data not available!"); + } + prevMemory = memory; + isPduInFlight = false; +} + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/beans/OneInterfaceBean.java b/src/main/java/uk/co/westhawk/snmp/beans/OneInterfaceBean.java new file mode 100644 index 0000000..bbc6d19 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/OneInterfaceBean.java @@ -0,0 +1,290 @@ +// NAME +// $RCSfile: OneInterfaceBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.14 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about one interface. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see #setIndex(int) + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see InterfaceGetNextPdu + * @see InterfaceIndexesBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.14 $ $Date: 2006/01/25 18:08:56 $ + */ +public class OneInterfaceBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: OneInterfaceBean.java,v 1.14 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + private InterfaceGetNextPdu pdu, prev; + + private boolean isPduInFlight; + private Date lastUpdateDate = null; + + private int index = 1; + private String descr = ""; + private String operState = ""; + private long speed = -1; + + +/** + * The default constructor. + */ +public OneInterfaceBean() +{ +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public OneInterfaceBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public OneInterfaceBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Sets the index of the interface that will be requested. + * @param i the index + * @see #getIndex() + */ +public void setIndex(int i) +{ + if (index != i) + { + index = i; + } +} + +/** + * Returns the index of the interface. + * @return the index + * @see #setIndex(int) + */ +public int getIndex() +{ + return index; +} + +/** + * Returns the description of the interface. + * @return the description + */ +public String getDescription() +{ + return descr; +} + +/** + * Returns the operation state of the interface. + * @return the operation state + */ +public String getOperStatusString() +{ + return operState; +} + +/** + * Returns the speed (bits per second) of the interface. + * @return the speed + */ +public long getSpeed() +{ + return speed; +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * This method starts sending the SNMP request. All properties should be + * set before this method is called. + * + * The actual sending will take place in the run method. + * It makes a new snmp context and initialises all variables before + * starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isPduInFlight = false; + setRunning(true); + } +} + + +/** + * The run method according to the Runnable interface. + * This method will send the Pdu request, if the previous one is not + * still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + if (isPduInFlight == false) + { + isPduInFlight = true; + prev = pdu; + try + { + pdu = new InterfaceGetNextPdu(context); + pdu.addObserver(this); + pdu.addOids(index-1); + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * The update method according to the Observer interface, it will be + * called when the Pdu response is received. + * The speed is calculated with the previous answer, after that the + * property change event is fired. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + if (prev != null) + { + speed = pdu.getSpeed(prev); + } + + descr = pdu.getIfDescr(); + operState = pdu.getIfOperStatusStr(); + + lastUpdateDate = new Date(); + isPduInFlight = false; + firePropertyChange("Interface", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/OneNTPrintQBean.java b/src/main/java/uk/co/westhawk/snmp/beans/OneNTPrintQBean.java new file mode 100644 index 0000000..81897f5 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/OneNTPrintQBean.java @@ -0,0 +1,290 @@ +// NAME +// $RCSfile: OneNTPrintQBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about one NT print queue installed + * on a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see #setIndex(String) + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetPdu_vec + * @see NTPrintQBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + */ +public class OneNTPrintQBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: OneNTPrintQBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + private GetPdu_vec pdu; + + private boolean isPduInFlight; + private Date lastUpdateDate = null; + + private String index = ""; + private String name = ""; + private int jobs = 0; + + private final static int NR_OID = 2; + private final static String svPrintQName = + "1.3.6.1.4.1.77.1.2.29.1.1"; + private final static String svPrintQNumJobs = + "1.3.6.1.4.1.77.1.2.29.1.2"; + +/** + * The default constructor. + */ +public OneNTPrintQBean() +{ +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public OneNTPrintQBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public OneNTPrintQBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + + +/** + * Sets the index of the NT print queue that will be requested. + * @param ind the index + * @see #getIndex() + * @see NTPrintQBean#getIndex(String) + */ +public void setIndex(String ind) +{ + if (ind != null && ind.length() > 0) + { + index = ind; + } +} + +/** + * Returns the index of the NT print queue. + * @return the index + * @see #setIndex(String) + */ +public String getIndex() +{ + return index; +} + +/** + * Returns the name of the NT print queue. + * @return the name + */ +public String getName() +{ + return name; +} + +/** + * Returns the number of jobs currently in this NT print queue. + * @return the number of jobs + */ +public int getNumJobs() +{ + return jobs; +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * This method starts sending the SNMP request. All properties should be + * set before this method is called. + * + * The actual sending will take place in the run method. + * It makes a new snmp context and initialises all variables before + * starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isPduInFlight = false; + setRunning(true); + } +} + + +/** + * The run method according to the Runnable interface. + * This method will send the Pdu request, if the previous one is not + * still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + String ind = getIndex(); + if (isPduInFlight == false && ind != null && ind.length() > 0) + { + isPduInFlight = true; + pdu = new GetPdu_vec(context, NR_OID); + pdu.addObserver(this); + pdu.addOid(svPrintQName + "." + ind); + pdu.addOid(svPrintQNumJobs + "." + ind); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * The update method according to the Observer interface, it will be + * called when the Pdu response is received. + * The property change event is fired. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + pdu = (GetPdu_vec) obs; + varbind [] varbinds = (varbind []) ov; + + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + name = ((AsnOctets) varbinds[0].getValue()).getValue(); + jobs = ((AsnInteger) varbinds[1].getValue()).getValue(); + + lastUpdateDate = new Date(); + isPduInFlight = false; + firePropertyChange("NTService", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/OneNTServiceBean.java b/src/main/java/uk/co/westhawk/snmp/beans/OneNTServiceBean.java new file mode 100644 index 0000000..0d89d26 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/OneNTServiceBean.java @@ -0,0 +1,371 @@ +// NAME +// $RCSfile: OneNTServiceBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about one NT network service installed + * on a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see #setIndex(String) + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetPdu_vec + * @see NTServiceNamesBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + */ +public class OneNTServiceBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: OneNTServiceBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + private GetPdu_vec pdu; + + private boolean isPduInFlight; + private Date lastUpdateDate = null; + + private String index = ""; + private String name = ""; + private String instState = ""; + private String operState = ""; + private boolean canUninst = false; + private boolean canPause = false; + + private final static int NR_OID = 5; + private final static String svSvcName = + "1.3.6.1.4.1.77.1.2.3.1.1"; + private final static String svSvcInstalledState = + "1.3.6.1.4.1.77.1.2.3.1.2"; + private final static String svSvcOperatingState = + "1.3.6.1.4.1.77.1.2.3.1.3"; + private final static String svSvcCanBeUninstalled = + "1.3.6.1.4.1.77.1.2.3.1.4"; + private final static String svSvcCanBePaused = + "1.3.6.1.4.1.77.1.2.3.1.5"; + + public final static String msg_inst_state[] = + { + "unknown", + "uninstalled", // 1 + "install pending", // 2 + "uninstall pending", // 3 + "installed" // 4 + }; + + public final static String msg_oper_state[] = + { + "unknown", + "active", // 1 + "continue pending", // 2 + "pause pending", // 3 + "paused" // 4 + }; + + public final static int cannot_be_uninstalled = 1; + public final static int can_be_uninstalled = 2; + + public final static int cannot_be_paused = 1; + public final static int can_be_paused = 2; + + +/** + * The default constructor. + */ +public OneNTServiceBean() +{ +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public OneNTServiceBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public OneNTServiceBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + +/** + * Sets the index of the NT network service that will be requested. + * @param ind the index + * @see #getIndex() + * @see NTServiceNamesBean#getIndex(String) + */ +public void setIndex(String ind) +{ + if (ind != null && ind.length() > 0) + { + index = ind; + } +} + +/** + * Returns the index of the NT network service. + * @return the index + * @see #setIndex(String) + */ +public String getIndex() +{ + return index; +} + +/** + * Returns the name of the NT network service. + * @return the name + */ +public String getName() +{ + return name; +} + +/** + * Returns the installation status of the NT network service. + * @return the installation status + * @see #msg_inst_state + */ +public String getInstalledState() +{ + return instState; +} + +/** + * Returns the operating status of the NT network service. + * @return the operating status + * @see #msg_oper_state + */ +public String getOperatingState() +{ + return operState; +} + +/** + * Returns if the NT network service can be uninstalled. + * @return the uninstalled option + * @see #can_be_uninstalled + * @see #cannot_be_uninstalled + */ +public boolean getCanBeUninstalled() +{ + return canUninst; +} + +/** + * Returns if the NT network service can be paused. + * @return the paused option + * @see #can_be_paused + * @see #cannot_be_paused + */ +public boolean getCanBePaused() +{ + return canPause; +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * This method starts sending the SNMP request. All properties should be + * set before this method is called. + * + * The actual sending will take place in the run method. + * It makes a new snmp context and initialises all variables before + * starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isPduInFlight = false; + setRunning(true); + } +} + + +/** + * The run method according to the Runnable interface. + * This method will send the Pdu request, if the previous one is not + * still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + String ind = getIndex(); + if (isPduInFlight == false && ind != null && ind.length() > 0) + { + isPduInFlight = true; + pdu = new GetPdu_vec(context, NR_OID); + pdu.addObserver(this); + pdu.addOid(svSvcName + "." + ind); + pdu.addOid(svSvcInstalledState + "." + ind); + pdu.addOid(svSvcOperatingState + "." + ind); + pdu.addOid(svSvcCanBeUninstalled + "." + ind); + pdu.addOid(svSvcCanBePaused + "." + ind); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * The update method according to the Observer interface, it will be + * called when the Pdu response is received. + * The property change event is fired. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + int nr; + pdu = (GetPdu_vec) obs; + varbind [] varbinds = (varbind []) ov; + + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + name = ((AsnOctets) varbinds[0].getValue()).getValue(); + + nr = ((AsnInteger) varbinds[1].getValue()).getValue(); + instState = msg_inst_state[nr]; + + nr = ((AsnInteger) varbinds[2].getValue()).getValue(); + operState = msg_oper_state[nr]; + + nr = ((AsnInteger) varbinds[3].getValue()).getValue(); + canUninst = (nr == can_be_uninstalled); + + nr = ((AsnInteger) varbinds[4].getValue()).getValue(); + canPause = (nr == can_be_paused); + + lastUpdateDate = new Date(); + isPduInFlight = false; + firePropertyChange("NTService", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/OneNTSharedResBean.java b/src/main/java/uk/co/westhawk/snmp/beans/OneNTSharedResBean.java new file mode 100644 index 0000000..1fc8261 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/OneNTSharedResBean.java @@ -0,0 +1,318 @@ +// NAME +// $RCSfile: OneNTSharedResBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2006/01/25 18:08:56 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean collects information about one NT shared resource installed + * on a NT server. The NT mib is described in the + * + * LAN Manager MIB II for Windows NT Objects . + * + * You will have to register to the MSDN before accessing this page. + *

    + * + *

    + * The properties in the parent classes should be set, before calling + * the action() method. Via a PropertyChangeEvent the application/applet + * will be notified. + *

    + * + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setCommunityName + * @see SNMPRunBean#setUpdateInterval + * @see #setIndex(String) + * @see SNMPBean#addPropertyChangeListener + * @see SNMPBean#action + * @see GetPdu_vec + * @see NTSharedResBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.13 $ $Date: 2006/01/25 18:08:56 $ + */ +public class OneNTSharedResBean extends SNMPRunBean implements Observer +{ + private static final String version_id = + "@(#)$Id: OneNTSharedResBean.java,v 1.13 2006/01/25 18:08:56 birgit Exp $ Copyright Westhawk Ltd"; + + private GetPdu_vec pdu; + + private boolean isPduInFlight; + private Date lastUpdateDate = null; + + private String index = ""; + private String name = ""; + private String path = ""; + private String comment = ""; + + private final static int NR_OID = 3; + private final static String svShareName = + "1.3.6.1.4.1.77.1.2.27.1.1"; + private final static String svSharePath = + "1.3.6.1.4.1.77.1.2.27.1.2"; + private final static String svShareComment = + "1.3.6.1.4.1.77.1.2.27.1.3"; + +/** + * The default constructor. + */ +public OneNTSharedResBean() +{ +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see SNMPBean#setHost + * @see SNMPBean#setPort + */ +public OneNTSharedResBean(String h, int p) +{ + this(h, p, null); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @see SNMPBean#setHost + * @see SNMPBean#setPort + * @see SNMPBean#setBindAddress + * + * @since 4_14 + */ +public OneNTSharedResBean(String h, int p, String b) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); +} + + +/** + * Sets the index of the NT shared resource that will be requested. + * @param ind the index + * @see #getIndex() + * @see NTSharedResBean#getIndex(String) + */ +public void setIndex(String ind) +{ + if (ind != null && ind.length() > 0) + { + index = ind; + } +} + +/** + * Returns the index of the NT shared resource. + * @return the index + * @see #setIndex(String) + */ +public String getIndex() +{ + return index; +} + +/** + * Returns the name of the NT shared resource. + * @return the name + */ +public String getName() +{ + return name; +} + +/** + * Returns the local name (path) of the NT shared resource. + * @return the path + */ +public String getPath() +{ + return path; +} + +/** + * Returns the comment associated with the NT shared resource. + * @return the comment + */ +public String getComment() +{ + return comment; +} + +/** + * Returns the date of the moment when this bean was last updated. + * This might be null when the first time the update was not finished. + * + * @return the last update date + */ +public Date getLastUpdateDate() +{ + return lastUpdateDate; +} + +/** + * This method starts sending the SNMP request. All properties should be + * set before this method is called. + * + * The actual sending will take place in the run method. + * It makes a new snmp context and initialises all variables before + * starting. + */ +public void action() +{ + if (isHostPortReachable()) + { + lastUpdateDate = new Date(); + isPduInFlight = false; + setRunning(true); + } +} + + +/** + * The run method according to the Runnable interface. + * This method will send the Pdu request, if the previous one is not + * still in flight. + * @see SNMPRunBean#isRunning() + */ +public void run() +{ + while (context != null && isRunning()) + { + String ind = getIndex(); + if (isPduInFlight == false && ind != null && ind.length() > 0) + { + isPduInFlight = true; + pdu = new GetPdu_vec(context, NR_OID); + pdu.addObserver(this); + pdu.addOid(svShareName + "." + ind); + pdu.addOid(svSharePath + "." + ind); + pdu.addOid(svShareComment + "." + ind); + try + { + pdu.send(); + } + catch (PduException exc) + { + System.out.println("PduException " + exc.getMessage()); + } + catch (IOException exc) + { + System.out.println("IOException " + exc.getMessage()); + } + } + + try + { + Thread.sleep(interval); + } + catch (InterruptedException ix) + { + ; + } + } +} + +/** + * The update method according to the Observer interface, it will be + * called when the Pdu response is received. + * The property change event is fired. + * + * @see SNMPBean#addPropertyChangeListener + */ +public void update(Observable obs, Object ov) +{ + pdu = (GetPdu_vec) obs; + varbind [] varbinds = (varbind []) ov; + + if (pdu.getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + AsnObject asnobj; + name = ((AsnOctets) varbinds[0].getValue()).getValue(); + + asnobj = varbinds[1].getValue(); + path = " "; + if (asnobj instanceof AsnOctets) + { + path = ((AsnOctets) asnobj).getValue(); + } + + asnobj = varbinds[2].getValue(); + comment = " "; + if (asnobj instanceof AsnOctets) + { + comment = ((AsnOctets) asnobj).getValue(); + } + + + lastUpdateDate = new Date(); + isPduInFlight = false; + firePropertyChange("NTService", null, null); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/SNMPBean.java b/src/main/java/uk/co/westhawk/snmp/beans/SNMPBean.java new file mode 100644 index 0000000..9f53f91 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/SNMPBean.java @@ -0,0 +1,473 @@ +// NAME +// $RCSfile: SNMPBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.12 $ +// CREATED +// $Date: 2006/01/26 12:38:30 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean forms the base of the SNMP beans. + *

    + * + *

    + * It provides the setting of the properties that are always needed when + * sending a SNMP request: + *

    + *
      + *
    • host, default is localhost
    • + *
    • port, default is 161
    • + *
    • community name, default is public
    • + *
    • bindAddr, default is null
    • + *
    • socket type, default is Standard
    • + *
    + * + *

    + * The bean will only come into action when the method action() is + * called. This should be done after the properties have been set. + *

    + * + *

    + * This bean also provide the methods for adding and removing property + * change listeners and firing property change events. + *

    + * + *

    + * Note: This bean will create a socket. This might result in a + * SecurityException because of the Java security policy. + *

    + *
      + *
    • + * If you are an applet: you're only connect back to its source web server + *
    • + *
    • + * If you are an application or servlet: java allows you to send it. The + * host might refuse your connection. + *
    • + *
    + * + *

    + * The SNMP request will only succeed if: + *

    + *
      + *
    • + * java security policy allows the opening of the socket + *
    • + *
    • + * the host/port combination is reachable from your location (you can + * check that with the ping (command line) command. + *
    • + *
    • + * the combination of OID and community name is correct + *
    • + *
    + * + * @see SNMPRunBean + * @see IsHostReachableBean + * @see OneInterfaceBean + * @see InterfaceIndexesBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.12 $ $Date: 2006/01/26 12:38:30 $ + * + */ +public abstract class SNMPBean +{ + private static final String version_id = + "@(#)$Id: SNMPBean.java,v 1.12 2006/01/26 12:38:30 birgit Exp $ Copyright Westhawk Ltd"; + + protected SnmpContext context = null; + + protected String host = "localhost"; + protected String bindAddr = null; + protected int port = 161; + protected String community = "public"; + protected String socketType = SnmpContextBasisFace.STANDARD_SOCKET; + protected String message = ""; + + protected Vector propertyChangeListener = null; + + +/** + * This method should send the SNMP request. All properties should be + * set before this method is called. + */ +public abstract void action() +throws PduException, IOException; + +/** + * The default constructor. + */ +public SNMPBean() +{ + propertyChangeListener = new Vector(); +} + +/** + * The constructor that will set the host and the port no. + * + * @param h the hostname + * @param p the port no + * @see #setHost + * @see #setPort + */ +public SNMPBean(String h, int p) +{ + this(h, p, null, SnmpContextBasisFace.STANDARD_SOCKET); +} + +/** + * The constructor that will set the host, the port no and the local + * bind address. + * + * @param h the hostname + * @param p the port no + * @param b the local bind address + * @param t the socket type + * @see #setHost + * @see #setPort + * @see #setBindAddress + * @see #setSocketType + * + * @since 4_14 + */ +public SNMPBean(String h, int p, String b, String t) +{ + this(); + setHost(h); + setPort(p); + setBindAddress(b); + setSocketType(t); +} + +/** + * Returns the host (name or ipadress) which is addressed. This is the + * host where the SNMP server is running. + * @return the name of the host + * @see #setHost + */ +public String getHost() +{ + return host; +} + +/** + * Sets the host (name or ipadress) which will be asked for the SNMP request. + * This is the host where the SNMP server is running. + * The default is localhost. + * + * This bean will only start the request when action is called. + * + * @see #getHost + */ +public void setHost(String h) +{ + if (h != null && h.length() > 0 && !host.equals(h)) + { + host = h; + } +} + +/** + * Returns the port no which is used. That is the no of the port on the + * host where the SNMP server is running. + * @see #setPort(int) + * @see #setPort(String) + */ +public int getPort() +{ + return port; +} + +/** + * Sets the port no which is used. That should be the no of the port on the + * host where the SNMP server is running. + * The default is 161. + * + * This bean will only start the request when action is called. + * + * @param p The number of the port + * @see #getPort + * @see #setPort(String) + */ +public void setPort(int p) +{ + if (p > 0 && port != p) + { + port = p; + } +} + +/** + * Sets the port no which is used as a String. + * + * @param p The number of the port as a String + * @see #getPort + * @see #setPort(int) + */ +public void setPort(String p) +{ + int pNo; + try + { + pNo = Integer.valueOf(p.trim()).intValue(); + setPort(pNo); + } + catch (NumberFormatException exp) + { + } +} + +/** + * Returns the community name that is used to send the SNMP request. + * @see #setCommunityName + */ +public String getCommunityName() +{ + return community; +} + +/** + * Sets the community name that is used to send the SNMP request. The + * default is public. + * @see #getCommunityName + */ +public void setCommunityName(String c) +{ + if (c != null & !community.equals(c)) + { + community = c; + if (context != null) + { + context.setCommunity(community); + } + } +} + +/** + * Returns the local bind address. + * @return the name of the local bind address + * @see #setBindAddress + * @since 4_14 + */ +public String getBindAddress() +{ + return bindAddr; +} + +/** + * Sets the local bind address. + * The default is null. + * + * This bean will only start the request when action is called. + * + * @see #getBindAddress + * @since 4_14 + */ +public void setBindAddress(String b) +{ + bindAddr = b; +} + + + +/** + * Returns the socket type. + * @return the socket type. + * @see #setSocketType + * @since 4_14 + */ +public String getSocketType() +{ + return socketType; +} + +/** + * Sets socket type. + * The default is null. + * + * This bean will only start the request when action is called. + * + * @see #getSocketType + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @since 4_14 + */ +public void setSocketType(String t) +{ + socketType = t; +} + + + +/** + * Indicates whether the host is reachable. + * This method will try to make a new SnmpContext, if this works, it is + * reachable. + * If it does not work, the message will be set. + * + * @see SnmpContext + */ +protected boolean isHostPortReachable() +{ + boolean res = true; + if (host != null + && + host.length() > 0 + && + port > 0) + { + try + { + if (context != null) + { + context.destroy(); + context = null; + } + + context = new SnmpContext(host, port, bindAddr, socketType); + context.setCommunity(community); + setMessage("Connection to host " + host + + " is made succesfully"); + } + catch (IOException exc) + { + res = false; + setMessage("IOException: " + exc.getMessage()); + } + catch (RuntimeException exc) + { + res = false; + setMessage("RuntimeException: " + exc.getMessage()); + } + } + else + { + res = false; + } + return res; +} + +/** + * Returns the message (if any). The message is used to give the user + * feedback if anything is happened with the request or the connection. + * + * @return the message + */ +public String getMessage() +{ + return message; +} + +/** + * Returns the message (if any). The message is used to give the user + * feedback if anything is happened (usually when something went wrong) + * with the connection. + * + * @param st the message string + * @see #getMessage() + */ +protected void setMessage(String st) +{ + message = st; +} + + +/** + * Add a property change listener. + * @see #removePropertyChangeListener + */ +public synchronized void addPropertyChangeListener(PropertyChangeListener l) +{ + propertyChangeListener.addElement(l); +} + +/** + * Remove a property change listener. + * @see #addPropertyChangeListener + */ +public synchronized void removePropertyChangeListener(PropertyChangeListener l) +{ + propertyChangeListener.removeElement(l); +} + +/** + * Fire the property event. + * + * @see #removePropertyChangeListener + * @see #addPropertyChangeListener + * @see PropertyChangeEvent + * @see PropertyChangeListener + */ +protected void firePropertyChange(String property, Object old_v, Object new_v) +{ + Vector listeners; + synchronized(this) + { + listeners = (Vector) propertyChangeListener.clone(); + } + + PropertyChangeEvent event = new PropertyChangeEvent(this, + property, old_v, new_v); + + int sz = listeners.size(); + for (int i=0; iTim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.awt.*; +import java.util.*; +import java.text.*; +import java.lang.*; +import java.io.*; +import java.beans.*; + +/** + *

    + * This bean forms the base of the Runnable SNMP beans. + * It extends the SNMPBean class. + *

    + * + *

    + * This bean is used when SNMP requests have to be sent continuously, + * instead of just once. + * For that purpose the update interval setUpdateInterval() can + * be set. The default value is 2000, i.e. 2 msec. + *

    + * + *

    + * When implementing an extention of this class, the method + * action() should + * be implemented. It should somehow start the run by calling + * setRunning(true). + * Stopping the thread might be called by the application or applet. + *

    + * + * @see OneInterfaceBean + * @see InterfaceIndexesBean + * + * @author Birgit Arkesteijn + * @version $Revision: 1.9 $ $Date: 2006/02/09 14:20:09 $ + */ +public abstract class SNMPRunBean extends SNMPBean implements Runnable +{ + private static final String version_id = + "@(#)$Id: SNMPRunBean.java,v 1.9 2006/02/09 14:20:09 birgit Exp $ Copyright Westhawk Ltd"; + + protected int interval = 2000; + protected Thread me = null; + protected boolean running = false; + + +/** + * Method according to the Runnable interface. This method should + * provide the continuous sending of a Pdu, with a sleeping interval set + * by setUpdateInterval(). + * + * @see #setUpdateInterval(int) + * @see #setRunning + */ +public abstract void run(); + + +/** + * The default constructor + */ +public SNMPRunBean() +{ +} + + +/** + * Returns the update interval. This is the interval that the + * bean will sleep between 2 requests. + * + * @return the update interval in msec + * @see #setUpdateInterval(int) + * @see #setUpdateInterval(String) + */ +public int getUpdateInterval() +{ + return interval; +} + +/** + * Sets the update interval. This is the interval that the + * bean will sleep between 2 requests. + * The default will be 2000 (= 2 sec). + * + * @param i the interval in msec + * @see #getUpdateInterval + * @see #setUpdateInterval(String) + */ +public void setUpdateInterval(int i) +{ + if (interval != i) + { + interval = i; + } +} + +/** + * Sets the update interval as String. + * + * @param i the interval in msec as String + * @see #getUpdateInterval + * @see #setUpdateInterval(int) + */ +public void setUpdateInterval(String i) +{ + int iNo; + try + { + iNo = Integer.valueOf(i.trim()).intValue(); + setUpdateInterval(iNo); + } + catch (NumberFormatException exp) + { + } +} + +/** + * Returns if the bean is running. + * @return the running mode + * @see #setRunning + */ +public boolean isRunning() +{ + return running; +} + +/** + * Starts or stops the thread. + * Starting this thread should be a result of calling the action() + * method, so should be implemented in the action method of any child + * class. + * + * Stopping this thread may be called by the application of applet. + * This method does NOT call Thread.stop() anymore. Every run() method + * should check isRunning(), so that when setRunning(false) is called, + * the run() method will stop running!! + * + * @see #isRunning + * @see SNMPBean#action() + */ +public synchronized void setRunning(boolean b) +{ + if (running != b) + { + running = b; + + if (running) + { + if (me == null) + { + me = new Thread(this); + me.setPriority(Thread.MIN_PRIORITY); + } + me.start(); + } + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/UsmBeingDiscoveredBean.java b/src/main/java/uk/co/westhawk/snmp/beans/UsmBeingDiscoveredBean.java new file mode 100644 index 0000000..0f96825 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/UsmBeingDiscoveredBean.java @@ -0,0 +1,313 @@ +// NAME +// $RCSfile: UsmBeingDiscoveredBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.8 $ +// CREATED +// $Date: 2009/03/05 15:51:42 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.util.*; +import java.util.*; + +/** + *

    + * This bean handles being discovered as an authoritative engine by an + * non-authoritative engine (SNMPv3 only). + *

    + * + *

    + * The discovery process consists of two steps: + * 1. first the SNMP engine ID has to be discovered, + * second the timeline details of the SNMP engine ID have to be discovered. + *
    + * 2. For the last step the username of the principal is needed. + *
    + * All these parameters should be provided by (your own) UsmAgent. + *

    + * + *

    + * This class is not very efficient. The private context + * discEngineIdContextIn will be the same for every SnmpContextv3 that + * creates this bean. + *

    + * + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * + * @see SnmpContextv3#addRequestPduListener + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.8 $ $Date: 2009/03/05 15:51:42 $ + */ +public class UsmBeingDiscoveredBean implements RequestPduListener +{ + private static final String version_id = + "@(#)$Id: UsmBeingDiscoveredBean.java,v 1.8 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd"; + + private UsmAgent usmAgent = null; + private SnmpContextv3 context = null; + + // the context to receive incoming requests + private SnmpContextv3Discovery discEngineIdContextIn; + private SnmpContextv3Discovery discTimeLineContextIn; + + // the context to send the answer back + private SnmpContextv3 discEngineIdContextOut; + private SnmpContextv3 discTimeLineContextOut; + +/** + * Constructor. + * + * @param myUsmAgent The usmAgent that will provide all the + * authoritative engine parameters + * @param myContext The context + * + * @see SnmpContextv3#addRequestPduListener + */ +public UsmBeingDiscoveredBean(SnmpContextv3 myContext, UsmAgent myUsmAgent) +throws java.io.IOException +{ + usmAgent = myUsmAgent; + context = myContext; + + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + " Constructor:" + + "usmAgent=" + usmAgent.toString() + + "context=" + context.toString()); + } + usmAgent.setSnmpContext(context); + + discEngineIdContextIn = new SnmpContextv3Discovery(context.getSendToHostAddress(), + context.getPort(), context.getBindAddress(), context.getTypeSocket()); + discEngineIdContextIn.setUserName(""); + discEngineIdContextIn.setUseAuthentication(false); + discEngineIdContextIn.setUsePrivacy(false); + discEngineIdContextIn.setContextEngineId(SnmpUtilities.toBytes(usmAgent.getSnmpEngineId())); + discEngineIdContextIn.setContextName(""); + discEngineIdContextIn.setUsmAgent(usmAgent); + + discTimeLineContextIn = new SnmpContextv3Discovery(context.getSendToHostAddress(), + context.getPort(), context.getBindAddress(), context.getTypeSocket()); + discTimeLineContextIn.setUserName(context.getUserName()); + discTimeLineContextIn.setUseAuthentication(context.isUseAuthentication()); + discTimeLineContextIn.setAuthenticationProtocol(context.getAuthenticationProtocol()); + discTimeLineContextIn.setUserAuthenticationPassword(context.getUserAuthenticationPassword()); + discTimeLineContextIn.setUsePrivacy(context.isUsePrivacy()); + discTimeLineContextIn.setPrivacyProtocol(context.getPrivacyProtocol()); + discTimeLineContextIn.setUserPrivacyPassword(context.getUserPrivacyPassword()); + discTimeLineContextIn.setContextEngineId(SnmpUtilities.toBytes(usmAgent.getSnmpEngineId())); + discTimeLineContextIn.setContextName(""); + discTimeLineContextIn.setUsmAgent(usmAgent); +} + +/** + * @param lcontext The listening context for incoming (discovery) requests + * @see SnmpContextv3#addRequestPduListener + */ +public void addRequestPduListener(ListeningContextPool lcontext) +throws java.io.IOException +{ + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + + ".addRequestPduListener(" + lcontext.toString() + ")"); + } + discEngineIdContextIn.addRequestPduListener(this, lcontext); + discTimeLineContextIn.addRequestPduListener(this, lcontext); +} + +/** + * @param lcontext Stop listening on this listening context for incoming (discovery) requests + * @see SnmpContextv3#removeRequestPduListener + */ +public void removeRequestPduListener(ListeningContextPool lcontext) +throws java.io.IOException +{ + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + + ".removeRequestPduListener(" + lcontext.toString() + ")"); + } + discEngineIdContextIn.removeRequestPduListener(this, lcontext); + discTimeLineContextIn.removeRequestPduListener(this, lcontext); +} + +/** + * Receiving an incoming (discovery) PDU request. + */ +public void requestPduReceived(RequestPduEvent evt) +{ + Object src = evt.getSource(); + int port = evt.getHostPort(); + Pdu orgPdu = evt.getPdu(); + if (src == discEngineIdContextIn) + { + sendEngineIdReport(orgPdu, port); + } + else + { + sendTimeLineReport(orgPdu, port); + } +} + +/** + * Send back the snmp engine ID. + */ +protected void sendEngineIdReport(Pdu orgPdu, int port) +{ + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendEngineIdReport()"); + } + + try + { + if (discEngineIdContextOut != null) + { + discEngineIdContextOut.destroy(); + } + discEngineIdContextOut = new SnmpContextv3(discEngineIdContextIn.getHost(), + port, discEngineIdContextIn.getBindAddress(), + discEngineIdContextIn.getTypeSocket()); + discEngineIdContextOut = (SnmpContextv3) discEngineIdContextIn.cloneParameters(discEngineIdContextOut); + + Pdu repPdu = new ReportPdu(discEngineIdContextOut, orgPdu); + repPdu.addOid(usmStatsConstants.usmStatsUnknownEngineIDs, + new AsnUnsInteger(usmAgent.getUsmStatsUnknownEngineIDs())); + repPdu.send(); + } + catch (java.io.IOException iexc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendEngineIdReport(): " + + "IOException: " + iexc.getMessage()); + } + } + catch (PduException pexc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendEngineIdReport(): " + + "PduException: " + pexc.getMessage()); + } + } +} + + +/** + * Send back the time lininess + */ +protected void sendTimeLineReport(Pdu orgPdu, int port) +{ + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendTimeLineReport()"); + } + + try + { + if (discTimeLineContextOut != null) + { + discTimeLineContextOut.destroy(); + } + discTimeLineContextOut = new SnmpContextv3(discTimeLineContextIn.getHost(), + port, discTimeLineContextIn.getBindAddress(), + discTimeLineContextIn.getTypeSocket()); + discTimeLineContextOut = (SnmpContextv3) discTimeLineContextIn.cloneParameters(discTimeLineContextOut); + + Pdu repPdu = new ReportPdu(discTimeLineContextOut, orgPdu); + repPdu.addOid(usmStatsConstants.usmStatsNotInTimeWindows, + new AsnUnsInteger(usmAgent.getUsmStatsNotInTimeWindows())); + repPdu.send(); + } + catch (java.io.IOException iexc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendTimeLineReport(): " + + "IOException: " + iexc.getMessage()); + } + } + catch (PduException pexc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".sendEngineIdReport(): " + + "PduException: " + pexc.getMessage()); + } + } +} + + +/** + * Destroys all the contexts in use. + */ +public void freeResources() +{ + discEngineIdContextIn.destroy(); + discEngineIdContextIn = null; + + discTimeLineContextIn.destroy(); + discTimeLineContextIn = null; + + if (discEngineIdContextOut != null) + { + discEngineIdContextOut.destroy(); + discEngineIdContextOut = null; + } + if (discTimeLineContextOut != null) + { + discTimeLineContextOut.destroy(); + discTimeLineContextOut = null; + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/beans/UsmDiscoveryBean.java b/src/main/java/uk/co/westhawk/snmp/beans/UsmDiscoveryBean.java new file mode 100644 index 0000000..e0ad24c --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/beans/UsmDiscoveryBean.java @@ -0,0 +1,361 @@ +// NAME +// $RCSfile: UsmDiscoveryBean.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.21 $ +// CREATED +// $Date: 2009/03/05 15:51:42 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.beans; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.util.*; + +/** + *

    + * This bean performs the SNMPv3 USM discovery process. + *

    + * + *

    + * The process consists of two steps: first the SNMP engine ID has to be + * discovered, second the timeline details of the SNMP engine ID have to + * be discovered. For the last step the username of the principal is + * needed. + *

    + * + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * + * @author Birgit Arkesteijn + * @version $Revision: 1.21 $ $Date: 2009/03/05 15:51:42 $ + */ +public class UsmDiscoveryBean +{ + private static final String version_id = + "@(#)$Id: UsmDiscoveryBean.java,v 1.21 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd"; + + private SnmpContextv3Pool context; + private String userName = null; + private String userAuthPassword = null; + private String userPrivPassword = null; + private int authProtocol, privProtocol; + private int retry_intervals[] = {500,1000,2000,5000,5000}; + +/** + * Constructor. + * + * @param host The host to discover + * @param port The port to discover + * @see SnmpContextv3#SnmpContextv3(String, int) + * @see #startDiscovery() + */ +public UsmDiscoveryBean(String host, int port) +throws java.io.IOException +{ + this(host, port, null, SnmpContextBasisFace.STANDARD_SOCKET); +} + +/** + * Constructor. + * + * @param host The host to discover + * @param port The port to discover + * @param bindAddr The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see SnmpContextv3#SnmpContextv3(String, int, String, String) + * @see #startDiscovery() + */ +public UsmDiscoveryBean(String host, int port, String bindAddr, String typeSocketA) +throws java.io.IOException +{ + context = new SnmpContextv3Pool(host, port, bindAddr, typeSocketA); +} + +/** + * Sets the user's authentication details. + * With these details the time line details will be retrieved. + * If the user details are not set, only the engine ID will be + * discovered. + * + *

    + * The time line details only need to be known when the user want to + * send authenticated message to this SNMP engine. + *

    + * + * @param newUserName The user name + * @param newUserPassword The user authentication password + * @param protocol The user authentication protocol + * + * @see SnmpContextv3#setUserName(String) + * @see SnmpContextv3#setUserAuthenticationPassword(String) + * @see SnmpContextv3#setAuthenticationProtocol(int) + */ +public void setAuthenticationDetails(String newUserName, String newUserPassword, + int protocol) +{ + userName = newUserName; + userAuthPassword = newUserPassword; + authProtocol = protocol; +} + +/** + * Sets the user's privacy details. + * With these details the time line details will be retrieved if needed. + * + *

    + * The time line details only need to be known when the user want to + * send authenticated message to this SNMP engine. + *

    + * + * @param newUserPassword The user privacy password + * + * @see SnmpContextv3#setUserPrivacyPassword(String) + */ +public void setPrivacyDetails(String newUserPassword, int protocol) +{ + userPrivPassword = newUserPassword; + privProtocol = protocol; +} + +/** + * Sets the retry intervals of the PDU. The length of the array + * corresponds with the number of retries. Each entry in the array + * is the number of milliseconds of each try. + * + *

    + * If used, please set before sending! + *

    + * + * The default is {500, 1000, 2000, 5000, 5000}. + * It is good practice to make the interval bigger with each retry, + * if the numbers are the same the chance of collision is higher. + * + * @param rinterval The interval in msec of each retry + * @see Pdu#setRetryIntervals(int[]) + */ +public void setRetryIntervals(int rinterval[]) +{ + retry_intervals = rinterval; +} + +/** + * Starts the discovery. This method will send a Pdu to discover the + * SNMP engine ID. Set the user details before calling this method, if + * you want the time line details to be discovered as well. + * + *

    + * This is a blocking call! It will return when it has done the whole + * discovery. + *

    + * + * @see #setAuthenticationDetails(String, String, int) + * @see #discoveryEngineId + * @see #discoveryTimeLine + */ +// Thanks to "Cochran, Steve A." ; +// freeResources(); is called before throwing an exception +public void startDiscovery() +throws PduException, java.io.IOException +{ + try + { + discoveryEngineId(); + } + catch (PduException exc) + { + // You shouldn't really get an exception when doing engineID + // discovery. + freeResources(); // <-- Steve + throw new PduException("Engine ID discovery: " + + exc.getMessage()); + } + + try + { + discoveryTimeLine(); + } + catch (PduException exc) + { + // You can get an exception for authPriv. I noticed that when + // testing against MG-SOFT. + // Only throw the exception if the timeline was not discovered. + + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = + tWindow.getSnmpEngineId(context.getSendToHostAddress(), + context.getPort()); + if (tWindow.isTimeLineKnown(engineId) == false) + { + freeResources(); // <-- Steve + throw new PduException("Timeline discovery: " + + exc.getMessage()); + } + } + + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".startDiscovery(): " + + "Done, context " + context.toString()); + } + + freeResources(); +} + +/** + * Destroy the context in use. + */ +public void freeResources() +{ + context.destroy(); + context = null; +} + + +/** + * Starts the discovery of the SNMP engine ID. + * + *

    + * This is a blocking call! It will return when it has done the whole + * discovery. + *

    + * + * @see #startDiscovery + * @see #discoveryTimeLine + */ +protected void discoveryEngineId() +throws PduException, java.io.IOException +{ + DiscoveryPdu pdu; + + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(context.getHost(), + context.getPort()); + + // Just check again to be sure + if (engineId == null) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".discoveryEngineId(): " + + "Starting discovery Engine ID ..."); + } + context.setUserName(""); + context.setUseAuthentication(false); + context.setUsePrivacy(false); + context.setContextEngineId(new byte[0]); + context.setContextName(""); + + pdu = new DiscoveryPdu(context); + pdu.setRetryIntervals(retry_intervals); + pdu.send(); + pdu.waitForSelf(); + varbind [] vars = pdu.getResponseVarbinds(); + } +} + +/** + * Starts the discovery of the Time line. + * + *

    + * This is a blocking call! It will return when it has done the whole + * discovery. + *

    + * + * @see #startDiscovery + * @see #discoveryEngineId + */ +protected void discoveryTimeLine() +throws PduException, java.io.IOException +{ + DiscoveryPdu pdu; + + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = + tWindow.getSnmpEngineId(context.getSendToHostAddress(), + context.getPort()); + + // The engineId should be known by now. + // Only do timeline discovery if it is not known yet. + if (tWindow.isTimeLineKnown(engineId) == false && userName != null) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".discoveryTimeLine(): " + + "Starting discovery Timeline ..."); + } + context.setUserName(userName); + context.setUserAuthenticationPassword(userAuthPassword); + context.setUseAuthentication(true); + context.setAuthenticationProtocol(authProtocol); + context.setContextEngineId(new byte[0]); + context.setContextName(""); + + if (userPrivPassword != null) + { + context.setUsePrivacy(true); + context.setUserPrivacyPassword(userPrivPassword); + context.setPrivacyProtocol(privProtocol); + } + else + { + context.setUsePrivacy(false); + } + + pdu = new DiscoveryPdu(context); + pdu.setRetryIntervals(retry_intervals); + pdu.send(); + pdu.waitForSelf(); + varbind [] vars = pdu.getResponseVarbinds(); + + if (AsnObject.debug > 4) + { + System.out.println("Did discovery time line"); + } + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/DecodedPduEvent.java b/src/main/java/uk/co/westhawk/snmp/event/DecodedPduEvent.java new file mode 100644 index 0000000..4633e76 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/DecodedPduEvent.java @@ -0,0 +1,131 @@ +// NAME +// $RCSfile: DecodedPduEvent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.5 $ +// CREATED +// $Date: 2006/02/09 14:30:18 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; + + +/** + * The DecodedPduEvent class. This class is delivered when a pdu is received. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.5 $ $Date: 2006/02/09 14:30:18 $ + */ +public abstract class DecodedPduEvent extends java.util.EventObject +{ + private static final String version_id = + "@(#)$Id: DecodedPduEvent.java,v 1.5 2006/02/09 14:30:18 birgit Exp $ Copyright Westhawk Ltd"; + + protected boolean consumed = false; + + private int hostPort = -1; + private Pdu pdu; + +/** + * The constructor for a decoded pdu event. The SnmpContext classes + * will fire decoded pdu events. + * + * @param source The source (SnmpContext) of the event + * @param p The pdu + * @param prt The remote port number of the host where the pdu came from + * + * @see #getHostPort() + * @see #getPdu() + */ +public DecodedPduEvent(Object source, Pdu p, int prt) +{ + super(source); + pdu = p; + hostPort = prt; +} + + + +/** + * The remote port number of the host where the pdu came from. + * + * @return The remote port number of the host or -1. + * + */ +public int getHostPort() +{ + return hostPort; +} + + +/** + * The pdu. The pdu is part of a decoded pdu event. + * + * @return The decoded Pdu. + */ +public Pdu getPdu() +{ + return pdu; +} + +/** + * Consumes this event so that it will not be sent to any other + * listeners. + */ +public void consume() +{ + consumed = true; +} + +/** + * Returns whether or not this event has been consumed. + * @see #consume + */ +public boolean isConsumed() +{ + return consumed; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RawPduEvent.java b/src/main/java/uk/co/westhawk/snmp/event/RawPduEvent.java new file mode 100644 index 0000000..62160fc --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RawPduEvent.java @@ -0,0 +1,173 @@ +// NAME +// $RCSfile: RawPduEvent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.5 $ +// CREATED +// $Date: 2006/02/09 14:30:18 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; + + +/** + * The RawPduEvent class. This class is delivered when a undecoded pdu + * is received. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.5 $ $Date: 2006/02/09 14:30:18 $ + */ +public class RawPduEvent extends java.util.EventObject +{ + private static final String version_id = + "@(#)$Id: RawPduEvent.java,v 1.5 2006/02/09 14:30:18 birgit Exp $ Copyright Westhawk Ltd"; + + protected boolean consumed = false; + + private int version; + private String hostAddress; + private int hostPort = -1; + private byte [] message; + + +/** + * The constructor for an undecoded pdu event. The ListeningContext + * class will fire undecoded pdu events. + * + * @param source The source (ListeningContext) of the event + * @param v The SNMP version of the pdu + * @param hn The IP address of the host where the pdu came from + * @param prt The remote port number of the host where the pdu came from + * @param mess The pdu in bytes + * + * @see #getVersion() + * @see #getHostAddress() + * @see #getHostPort() + * @see #getMessage() + */ +public RawPduEvent(Object source, int v, String hn, byte [] mess, int prt) +{ + super(source); + version = v; + hostAddress = hn; + message = mess; + hostPort = prt; +} + +/** + * The SNMP version number of the pdu. + * + * @return The version number. + * @see #getHostAddress() + * @see #getMessage() + * @see SnmpConstants#SNMP_VERSION_1 + * @see SnmpConstants#SNMP_VERSION_2c + * @see SnmpConstants#SNMP_VERSION_3 + */ +public int getVersion() +{ + return version; +} + +/** + * The IP address of the host where the pdu came from. + * Note, this is not necessarily the same as the IpAddress field in the + * SNMPv1 Pdu. + * + * @return The IP address of the host or null. + * @see #getVersion() + * @see #getMessage() + */ +public String getHostAddress() +{ + return hostAddress; +} + +/** + * The pdu SNMP message in bytes. This is a copy of the original + * message. + * + * @return The pdu in bytes. + * @see #getVersion() + * @see #getHostAddress() + */ +public byte [] getMessage() +{ + return message; +} + +/** + * The remote port number of the host where the pdu came from. + * + * @return The remote port number of the host or -1. + * @see #getVersion() + * @see #getMessage() + * + */ +public int getHostPort() +{ + return hostPort; +} + + +/** + * Consumes this event so that it will not be sent to any other + * listeners. + */ +public void consume() +{ + consumed = true; +} + +/** + * Returns whether or not this event has been consumed. + * @see #consume + */ +public boolean isConsumed() +{ + return consumed; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RawPduListener.java b/src/main/java/uk/co/westhawk/snmp/event/RawPduListener.java new file mode 100644 index 0000000..561f1e9 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RawPduListener.java @@ -0,0 +1,70 @@ +// NAME +// $RCSfile: RawPduListener.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.3 $ +// CREATED +// $Date: 2006/01/17 17:59:33 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * The listener interface for receiving raw pdu events. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.3 $ $Date: 2006/01/17 17:59:33 $ + */ +public interface RawPduListener extends java.util.EventListener +{ + public static final String version_id = + "@(#)$Id: RawPduListener.java,v 1.3 2006/01/17 17:59:33 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Invoked when a pdu is received. + */ +public void rawPduReceived(RawPduEvent evt); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RawPduReceivedSupport.java b/src/main/java/uk/co/westhawk/snmp/event/RawPduReceivedSupport.java new file mode 100644 index 0000000..1f28f66 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RawPduReceivedSupport.java @@ -0,0 +1,179 @@ +// NAME +// $RCSfile: RawPduReceivedSupport.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.5 $ +// CREATED +// $Date: 2006/02/09 14:30:18 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.stack.*; + +/** + * This is a utility class that can be used by classes that support + * raw pdu listener functionality. + * You can use an instance of this class as a member field + * of your class and delegate various work to it. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.5 $ $Date: 2006/02/09 14:30:18 $ + */ +public class RawPduReceivedSupport +{ + public static final String version_id = + "@(#)$Id: RawPduReceivedSupport.java,v 1.5 2006/02/09 14:30:18 birgit Exp $ Copyright Westhawk Ltd"; + + private Object source; + private transient Vector pduListeners; + +/** + * The constructor. + * + * @param src The source (ListeningContext) of the pdu events when they are fired. + */ +public RawPduReceivedSupport(Object src) +{ + source = src; +} + +/** + * Removes all the listeners. + */ +public synchronized void empty() +{ + if (pduListeners != null) + { + pduListeners.removeAllElements(); + } +} + +/** + * Returns the number of listeners. + * + * @return The number of listeners. + */ +public synchronized int getListenerCount() +{ + int c=0; + if (pduListeners != null) + { + c = pduListeners.size(); + } + return c; +} + +/** + * Adds the specified pdu listener to receive pdus. + */ +public synchronized void addRawPduListener(RawPduListener listener) +{ + if (pduListeners == null) + { + pduListeners = new Vector (5); + } + if (pduListeners.contains(listener) == false) + { + pduListeners.addElement(listener); + } +} + +/** + * Removes the specified pdu listener. + */ +public synchronized void removeRawPduListener(RawPduListener listener) +{ + if (pduListeners != null) + { + pduListeners.removeElement(listener); + } +} + + +/** + * Fires an undecoded pdu event. + * The event is fired to all listeners, unless one of them consumes it. + * The idea is that for undecoded pdus it is very unlikely that more + * than one party (usually SnmpContext objects) is interested. + * + * @param version The SNMP version of the pdu + * @param hostAddress The IP address of the host where the pdu came from + * @param hostPort The remote port number of the host where the pdu came from + * @param message The pdu in bytes + * + * @return Whether or not the event has been consumed. + */ +public boolean fireRawPduReceived(int version, String hostAddress, int hostPort, byte [] message) +{ + boolean isConsumed = false; + Vector copyOfListeners = null; + if (pduListeners != null) + { + synchronized (pduListeners) + { + copyOfListeners = (Vector) pduListeners.clone(); + } + } + + if (copyOfListeners != null) + { + int l = message.length; + int sz = copyOfListeners.size(); + for (int i=sz-1; i>=0 && isConsumed == false; i--) + { + RawPduListener listener = (RawPduListener) copyOfListeners.elementAt(i); + + byte [] copyOfMessage = new byte[l]; + System.arraycopy(message, 0, copyOfMessage, 0, l); + RawPduEvent evt = new RawPduEvent(source, version, hostAddress, copyOfMessage, hostPort); + listener.rawPduReceived(evt); + isConsumed = (evt.isConsumed()); + } + } + return isConsumed; +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RequestPduEvent.java b/src/main/java/uk/co/westhawk/snmp/event/RequestPduEvent.java new file mode 100644 index 0000000..3669caf --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RequestPduEvent.java @@ -0,0 +1,88 @@ +// NAME +// $RCSfile: RequestPduEvent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.5 $ +// CREATED +// $Date: 2006/02/09 14:30:18 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; + + +/** + * The RequestPduEvent class. This class is delivered when a pdu is received. + * + *

    + * RequestPduEvents are fired in case of a GetRequest, SetRequest, + * GetNextRequest, GetBulkRequest (SNMPv2c, SNMPv3), Inform + * (SNMPv2c, SNMPv3) PDU that could be decoded and matched by one + * of the SnmpContext classes. + *

    + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.5 $ $Date: 2006/02/09 14:30:18 $ + */ +public class RequestPduEvent extends DecodedPduEvent +{ + private static final String version_id = + "@(#)$Id: RequestPduEvent.java,v 1.5 2006/02/09 14:30:18 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * The constructor for a decoded request pdu event. The SnmpContext + * classes will fire decoded request pdu events. + * + * @param source The source (SnmpContext) of the event + * @param pdu The pdu + * @param port The remote port number of the host where the pdu came from + * + */ +public RequestPduEvent(Object source, Pdu pdu, int port) +{ + super(source, pdu, port); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RequestPduListener.java b/src/main/java/uk/co/westhawk/snmp/event/RequestPduListener.java new file mode 100644 index 0000000..3321bf9 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RequestPduListener.java @@ -0,0 +1,70 @@ +// NAME +// $RCSfile: RequestPduListener.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.3 $ +// CREATED +// $Date: 2006/01/17 17:59:33 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * The listener interface for receiving decoded request pdu events. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.3 $ $Date: 2006/01/17 17:59:33 $ + */ +public interface RequestPduListener extends java.util.EventListener +{ + public static final String version_id = + "@(#)$Id: RequestPduListener.java,v 1.3 2006/01/17 17:59:33 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Invoked when a pdu is received. + */ +public void requestPduReceived(RequestPduEvent evt); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/RequestPduReceivedSupport.java b/src/main/java/uk/co/westhawk/snmp/event/RequestPduReceivedSupport.java new file mode 100644 index 0000000..25eb446 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/RequestPduReceivedSupport.java @@ -0,0 +1,165 @@ +// NAME +// $RCSfile: RequestPduReceivedSupport.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.4 $ +// CREATED +// $Date: 2006/01/17 17:59:33 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.stack.*; + +/** + * This is a utility class that can be used by classes that support + * request pdu listener functionality. + * You can use an instance of this class as a member field + * of your class and delegate various work to it. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.4 $ $Date: 2006/01/17 17:59:33 $ + */ +public class RequestPduReceivedSupport +{ + public static final String version_id = + "@(#)$Id: RequestPduReceivedSupport.java,v 1.4 2006/01/17 17:59:33 birgit Exp $ Copyright Westhawk Ltd"; + + private Object source; + private transient Vector pduListeners; + +/** + * The constructor. + * + * @param src The source (SnmpContext) of the pdu events when they are fired. + */ +public RequestPduReceivedSupport(Object src) +{ + source = src; +} + +/** + * Removes all the listeners. + */ +public synchronized void empty() +{ + if (pduListeners != null) + { + pduListeners.removeAllElements(); + } +} + +/** + * Returns the number of listeners. + * + * @return The number of listeners. + */ +public synchronized int getListenerCount() +{ + int c=0; + if (pduListeners != null) + { + c = pduListeners.size(); + } + return c; +} + +/** + * Adds the specified pdu listener to receive pdus. + */ +public synchronized void addRequestPduListener(RequestPduListener listener) +{ + if (pduListeners == null) + { + pduListeners = new Vector (5); + } + if (pduListeners.contains(listener) == false) + { + pduListeners.addElement(listener); + } +} + +/** + * Removes the specified pdu listener. + */ +public synchronized void removeRequestPduListener(RequestPduListener listener) +{ + if (pduListeners != null) + { + pduListeners.removeElement(listener); + } +} + + +/** + * Fires a decoded pdu event. + * The event is fired to all listeners, whether they consume it or not. + * + * @param pdu The decoded pdu pdu. + */ +public void fireRequestPduReceived(Pdu pdu, int hostPort) +{ + Vector copyOfListeners = null; + if (pduListeners != null) + { + synchronized (pduListeners) + { + copyOfListeners = (Vector) pduListeners.clone(); + } + } + + if (copyOfListeners != null) + { + int sz = copyOfListeners.size(); + for (int i=sz-1; i>=0; i--) + { + RequestPduListener listener = (RequestPduListener) copyOfListeners.elementAt(i); + + RequestPduEvent evt = new RequestPduEvent(source, pdu, hostPort); + listener.requestPduReceived(evt); + } + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/TrapEvent.java b/src/main/java/uk/co/westhawk/snmp/event/TrapEvent.java new file mode 100644 index 0000000..3a77b81 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/TrapEvent.java @@ -0,0 +1,81 @@ +// NAME +// $RCSfile: TrapEvent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.8 $ +// CREATED +// $Date: 2006/02/09 14:30:18 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; + + +/** + * The TrapEvent class. This class is delivered when a trap is received. + * + * @author Birgit Arkesteijn + * @version $Revision: 1.8 $ $Date: 2006/02/09 14:30:18 $ + */ +public class TrapEvent extends DecodedPduEvent +{ + private static final String version_id = + "@(#)$Id: TrapEvent.java,v 1.8 2006/02/09 14:30:18 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * The constructor for a decoded trap pdu event. The SnmpContext + * classes will fire decoded trap pdu events. + * + * @param source The source (SnmpContext) of the event + * @param pdu The pdu + * @param port The remote port number of the host where the pdu came from + * + */ +public TrapEvent(Object source, Pdu pdu, int port) +{ + super(source, pdu, port); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/TrapListener.java b/src/main/java/uk/co/westhawk/snmp/event/TrapListener.java new file mode 100644 index 0000000..5827d4f --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/TrapListener.java @@ -0,0 +1,69 @@ +// NAME +// $RCSfile: TrapListener.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.5 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + + +/** + * The listener interface for receiving decoded trap events. + * + * @author Birgit Arkesteijn + * @version $Revision: 1.5 $ $Date: 2006/01/17 17:43:53 $ + */ +public interface TrapListener extends java.util.EventListener +{ + public static final String version_id = + "@(#)$Id: TrapListener.java,v 1.5 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Invoked when a trap is received. + */ +public void trapReceived(TrapEvent evt); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/event/TrapReceivedSupport.java b/src/main/java/uk/co/westhawk/snmp/event/TrapReceivedSupport.java new file mode 100644 index 0000000..7c23890 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/event/TrapReceivedSupport.java @@ -0,0 +1,165 @@ +// NAME +// $RCSfile: TrapReceivedSupport.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.6 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ +package uk.co.westhawk.snmp.event; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.stack.*; + +/** + * This is a utility class that can be used by classes that support trap + * listener functionality. + * You can use an instance of this class as a member field + * of your class and delegate various work to it. + * + * @author Birgit Arkesteijn + * @version $Revision: 1.6 $ $Date: 2006/01/17 17:43:53 $ + */ +public class TrapReceivedSupport +{ + public static final String version_id = + "@(#)$Id: TrapReceivedSupport.java,v 1.6 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + private Object source; + private transient Vector trapListeners; + +/** + * The constructor. + * + * @param src The source (SnmpContext) of the trap events when they are fired. + */ +public TrapReceivedSupport(Object src) +{ + source = src; +} + +/** + * Removes all the listeners. + */ +public synchronized void empty() +{ + if (trapListeners != null) + { + trapListeners.removeAllElements(); + } +} + +/** + * Returns the number of listeners. + * + * @return The number of listeners. + */ +public synchronized int getListenerCount() +{ + int c=0; + if (trapListeners != null) + { + c = trapListeners.size(); + } + return c; +} + +/** + * Adds the specified trap listener to receive traps. + */ +public synchronized void addTrapListener(TrapListener listener) +{ + if (trapListeners == null) + { + trapListeners = new Vector (5); + } + if (trapListeners.contains(listener) == false) + { + trapListeners.addElement(listener); + } +} + +/** + * Removes the specified trap listener. + */ +public synchronized void removeTrapListener(TrapListener listener) +{ + if (trapListeners != null) + { + trapListeners.removeElement(listener); + } +} + + +/** + * Fires a decoded trap event. + * The event is fired to all listeners, whether they consume it or not. + * This behaviour is different from the undecoded trap event. + * + * @param pdu The decoded trap pdu. + */ +public void fireTrapReceived(Pdu pdu, int hostPort) +{ + Vector copyOfListeners = null; + if (trapListeners != null) + { + synchronized (trapListeners) + { + copyOfListeners = (Vector) trapListeners.clone(); + } + } + + if (copyOfListeners != null) + { + int sz = copyOfListeners.size(); + for (int i=sz-1; i>=0; i--) + { + TrapListener listener = (TrapListener) copyOfListeners.elementAt(i); + + TrapEvent evt = new TrapEvent(source, pdu, hostPort); + listener.trapReceived(evt); + } + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/net/ContextSocketFace.java b/src/main/java/uk/co/westhawk/snmp/net/ContextSocketFace.java new file mode 100644 index 0000000..369eb6b --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/net/ContextSocketFace.java @@ -0,0 +1,152 @@ +// NAME +// $RCSfile: ContextSocketFace.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.12 $ +// CREATED +// $Date: 2006/02/09 14:30:19 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.net; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; + +/** + * The interface for the different type of sockets. + * + * @author Tim Panton + * @version $Revision: 1.12 $ $Date: 2006/02/09 14:30:19 $ + */ +public interface ContextSocketFace +{ + static final String version_id = + "@(#)$Id: ContextSocketFace.java,v 1.12 2006/02/09 14:30:19 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Creates the socket. This socket is used when listening for incoming + * requests or traps. + * Use only one (1) of the two create methods. + * + * @param port The local port number were we receive (listen for) + * packets + * @param bindAddr The local address the server will bind to when + * listening + * + * @see #create(String, int, String) + */ +public void create(int port, String bindAddr) throws IOException; + +/** + * Creates the socket. This socket is used to send out our requests. Use + * only one (1) of the two create methods. + * + * @param host The name of the host that is to receive our packets + * @param port The port number of the host + * @param bindAddr The local address the server will bind to when + * sending packets + * + * @see #create(int, String) + */ +public void create(String host, int port, String bindAddr) throws IOException; + +/** + * Returns the IP address of the host we sent the packet to. + * Only applicable when sending requests, not when (only) listening for + * incoming requests or traps. + * + * @return The IP address, or null when the hostname cannot be determined + * @see #getReceivedFromHostAddress + */ +public String getSendToHostAddress(); + +/** + * Returns the IP address of the (latest) host of the packet we received. + * Only applicable when anything has been received. + * When sending a request, this will in most cases be the same host + * where we sent the original packet to. + * + * @return The IP address, or null when the hostname cannot be determined + * @see #getSendToHostAddress + */ +public String getReceivedFromHostAddress(); + +/** + * Returns the address of the endpoint this socket is bound to, or null + * if it is not bound yet. + * + * @since 4_14 + */ +public String getLocalSocketAddress(); + +/** + * Returns the address of the endpoint this socket is connected to, or + * null if it is unconnected. + * + * @since 4_14 + */ +public String getRemoteSocketAddress(); + +/** + * Receives a packet from this socket. The StreamPortItem object + * contains the host and port the packet came from. + * + * @param maxRecvSize the maximum number of bytes to receive + * @return the packet + */ +public StreamPortItem receive(int maxRecvSize) throws IOException; + +/** + * Sends a packet from this socket. + * It can throw an "java.io.IOException: Invalid argument" when the + * bind address is incorrect for some reason. + * + * @param packet the packet + */ +public void send(byte[] packet) throws IOException; + +/** + * Closes this socket. + */ +public void close(); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/net/StandardSocket.java b/src/main/java/uk/co/westhawk/snmp/net/StandardSocket.java new file mode 100644 index 0000000..52939d0 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/net/StandardSocket.java @@ -0,0 +1,224 @@ +// NAME +// $RCSfile: StandardSocket.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.13 $ +// CREATED +// $Date: 2009/03/05 15:56:19 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.net; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.net.*; +import uk.co.westhawk.snmp.stack.*; + +/** + * This is a wrapper class around the standard DatagramSocket. This + * sends packets over UDP, which is standard in SNMP. + * + * @see DatagramSocket + * @author Tim Panton + * @version $Revision: 1.13 $ $Date: 2009/03/05 15:56:19 $ + */ +public class StandardSocket implements ContextSocketFace +{ + static final String version_id = + "@(#)$Id: StandardSocket.java,v 1.13 2009/03/05 15:56:19 birgita Exp $ Copyright Westhawk Ltd"; + + private DatagramSocket soc=null; + private InetAddress sendToHostAddr; + private int sendToHostPort; + private InetAddress receiveFromHostAddr; + private int receiveFromHostPort; + private InetAddress locBindAddr = null; + +public StandardSocket() +{ +} + +public void create(int port, String bindAddr) throws IOException +{ + sendToHostPort = port; + receiveFromHostPort = sendToHostPort; // initialise (once!) + try + { + locBindAddr = null; + if (bindAddr != null) + { + locBindAddr = InetAddress.getByName(bindAddr); + } + soc = new DatagramSocket(sendToHostPort, locBindAddr); + } + catch (SocketException exc) + { + String str = "Socket problem: port=" + port + ", bindAddr=" + + bindAddr + " " + exc.getMessage(); + throw (new IOException(str)); + } +} + + +public void create(String host, int port, String bindAddr) throws IOException +{ + sendToHostPort = port; + receiveFromHostPort = sendToHostPort; // initialise (once!) + try + { + sendToHostAddr = InetAddress.getByName(host); + receiveFromHostAddr = sendToHostAddr; // initialise (once!) + locBindAddr = null; + if (bindAddr != null) + { + locBindAddr = InetAddress.getByName(bindAddr); + } + InetSocketAddress isa = new InetSocketAddress(locBindAddr, 0); + soc = new DatagramSocket(isa); + } + catch (SocketException exc) + { + String str = "Socket problem: host=" + host + ", port=" + port + + ", bindAddr=" + bindAddr + " " + exc.getMessage(); + throw (new IOException(str)); + } + catch (UnknownHostException exc) + { + String str = "Cannot find host " + host + " " + exc.getMessage(); + throw (new IOException(str)); + } +} + +public String getReceivedFromHostAddress() +{ + String res = null; + if (receiveFromHostAddr != null) + { + res = receiveFromHostAddr.getHostAddress(); + } + return res; +} + +public String getSendToHostAddress() +{ + String res = null; + if (sendToHostAddr != null) + { + res = sendToHostAddr.getHostAddress(); + } + return res; +} + +public String getLocalSocketAddress() +{ + String res = null; + if (soc != null) + { + SocketAddress sa = soc.getLocalSocketAddress(); + if (sa != null) + { + res = sa.toString(); + } + } + return res; +} + +public String getRemoteSocketAddress() +{ + String res = null; + if (soc != null) + { + SocketAddress sa = soc.getRemoteSocketAddress(); + if (sa != null) + { + res = sa.toString(); + } + } + return res; +} + +public StreamPortItem receive(int maxRecvSize) throws IOException +{ + StreamPortItem item = null; + if (soc != null) + { + byte [] data = new byte[maxRecvSize]; + DatagramPacket p = new DatagramPacket(data, maxRecvSize); + + // timeout will throw an exception every 1000 secs whilst idle + // it is caught and ignored, but as a side effect it loops, + // checking 'me' + soc.setSoTimeout(1000); + + soc.receive(p); + receiveFromHostAddr = p.getAddress(); + receiveFromHostPort = p.getPort(); + + ByteArrayInputStream in = null; + in = new ByteArrayInputStream(p.getData(), 0, p.getLength()); + item = new StreamPortItem(receiveFromHostAddr.getHostAddress(), + receiveFromHostPort, in); + p = null; + } + return item; +} + +public void send(byte[] packet) throws IOException +{ + if (soc != null) + { + DatagramPacket pack = new DatagramPacket(packet, packet.length, + sendToHostAddr, sendToHostPort); + soc.send(pack); + } +} + +public void close() +{ + if (soc != null) + { + soc.close(); + soc = null; + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/net/StreamPortItem.java b/src/main/java/uk/co/westhawk/snmp/net/StreamPortItem.java new file mode 100644 index 0000000..4306f3f --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/net/StreamPortItem.java @@ -0,0 +1,131 @@ +// NAME +// $RCSfile: StreamPortItem.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.4 $ +// CREATED +// $Date: 2006/02/09 14:14:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.net; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; + +/** + * This is a holder class that associates the incoming packet stream + * with the remote port it came from. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.4 $ $Date: 2006/02/09 14:14:50 $ + */ +public class StreamPortItem +{ + static final String version_id = + "@(#)$Id: StreamPortItem.java,v 1.4 2006/02/09 14:14:50 birgit Exp $ Copyright Westhawk Ltd"; + + private String hostAddress; + private int port; + private ByteArrayInputStream stream; + +/** + * Constructor. + * + * @param address The host address + * @param newPort The remote port number + * @param in The incoming message + */ +public StreamPortItem(String address, int newPort, ByteArrayInputStream in) +{ + hostAddress = address; + port = newPort; + stream = in; +} + +/** + * Returns the host addres where the message came from. + * + * @return The host address + */ +public String getHostAddress() +{ + return hostAddress; +} + +/** + * Returns the remote port where the message came from. + * + * @return The remote port number + */ +public int getHostPort() +{ + return port; +} + +/** + * Returns incoming message (or a copy of it). + * + * @return The message + */ +public ByteArrayInputStream getStream() +{ + return stream; +} + +/** + * Returns the string representation. + * + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer(getClass().getName()); + buffer.append("["); + buffer.append("hostAddress=").append(hostAddress); + buffer.append(", hostPort=").append(port); + buffer.append(", #bytes=").append(stream.available()); + buffer.append("]"); + return buffer.toString(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/net/TCPSocket.java b/src/main/java/uk/co/westhawk/snmp/net/TCPSocket.java new file mode 100644 index 0000000..6ceced3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/net/TCPSocket.java @@ -0,0 +1,296 @@ +// NAME +// $RCSfile: TCPSocket.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.8 $ +// CREATED +// $Date: 2009/03/05 15:56:19 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.net; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.net.*; +import uk.co.westhawk.snmp.stack.*; + +/** + * This is a wrapper class around the standard Socket. This sends + * packets over TCP. + * + *

    + * This is part of what is called "Reliable SNMP". SNMP usually goes + * over UDP. That is why there is a retry mechanisme in SNMP. Sending + * SNMP over TCP will only work is your agent listens on TCP. + * See + * RFC 3430 + *

    + * + *

    + * When listening for incoming packets, the Socket, that is created when + * accepting an incoming connection, is closed at the end. + * Because of this, it is NOT possible to send a response back over the + * same connection. + *

    + * + * @see Socket + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 1.8 $ $Date: 2009/03/05 15:56:19 $ + */ +public class TCPSocket implements ContextSocketFace +{ + static final String version_id = + "@(#)$Id: TCPSocket.java,v 1.8 2009/03/05 15:56:19 birgita Exp $ Copyright Westhawk Ltd"; + + private ServerSocket serverSoc=null; + private Socket clientSoc=null; + private InetAddress sendToHostAddr; + private int sendToHostPort; + private InetAddress receiveFromHostAddr; + private int receiveFromHostPort; + private InetAddress locBindAddr; + +public TCPSocket() +{ +} + +public void create(int port, String bindAddr) throws IOException +{ + sendToHostPort = port; + receiveFromHostPort = sendToHostPort; // initialise (once!) + try + { + locBindAddr = null; + if (bindAddr != null) + { + locBindAddr = InetAddress.getByName(bindAddr); + } + serverSoc = new ServerSocket(sendToHostPort, 50, locBindAddr); + } + catch (SocketException exc) + { + String str = "Socket problem: port=" + port + ", bindAddr=" + + bindAddr + " " + exc.getMessage(); + throw (new IOException(str)); + } +} + + +public void create(String host, int port, String bindAddr) throws IOException +{ + sendToHostPort = port; + receiveFromHostPort = sendToHostPort; // initialise (once!) + try + { + sendToHostAddr = InetAddress.getByName(host); + receiveFromHostAddr = sendToHostAddr; // initialise (once!) + locBindAddr = null; + if (bindAddr != null) + { + locBindAddr = InetAddress.getByName(bindAddr); + } + clientSoc = new Socket(sendToHostAddr, sendToHostPort, locBindAddr, 0); + } + catch (SocketException exc) + { + String str = "Socket problem: host=" + host + ", port=" + port + + ", bindAddr=" + bindAddr + " " + exc.getMessage(); + throw (new IOException(str)); + } + catch (UnknownHostException exc) + { + String str = "Cannot find host " + host + " " + exc.getMessage(); + throw (new IOException(str)); + } +} + +public String getReceivedFromHostAddress() +{ + String res = null; + if (receiveFromHostAddr != null) + { + res = receiveFromHostAddr.getHostAddress(); + } + return res; +} + +public String getSendToHostAddress() +{ + String res = null; + if (sendToHostAddr != null) + { + res = sendToHostAddr.getHostAddress(); + } + return res; +} + +public String getLocalSocketAddress() +{ + String res = null; + if (serverSoc != null) + { + SocketAddress sa = serverSoc.getLocalSocketAddress(); + if (sa != null) + { + res = sa.toString(); + } + } + else if (clientSoc != null) + { + SocketAddress sa = clientSoc.getLocalSocketAddress(); + if (sa != null) + { + res = sa.toString(); + } + } + return res; +} + +public String getRemoteSocketAddress() +{ + String res = null; + if (clientSoc != null) + { + SocketAddress sa = clientSoc.getRemoteSocketAddress(); + if (sa != null) + { + res = sa.toString(); + } + } + else if (serverSoc != null) + { + // + } + return res; +} + +public StreamPortItem receive(int maxRecvSize) throws IOException +{ + StreamPortItem item = null; + if (serverSoc != null) + { + byte [] data = new byte[maxRecvSize]; + + // timeout will throw an exception every 1000 secs whilst idle + // it is caught and ignored, but as a side effect it loops, + // checking 'me' + serverSoc.setSoTimeout(1000); + + Socket newSocket = serverSoc.accept(); + + // copy newSocketIn into in + InputStream newSocketIn = newSocket.getInputStream(); + newSocketIn.read(data, 0, data.length); + + receiveFromHostAddr = newSocket.getInetAddress(); + receiveFromHostPort = newSocket.getPort(); + + ByteArrayInputStream in = null; + in = new ByteArrayInputStream(data, 0, data.length); + item = new StreamPortItem(receiveFromHostAddr.getHostAddress(), + receiveFromHostPort, in); + + newSocketIn.close(); + newSocket.close(); + + newSocketIn = null; + newSocket = null; + } + else if (clientSoc != null) + { + byte [] data = new byte[maxRecvSize]; + + // timeout will throw an exception every 1000 secs whilst idle + // it is caught and ignored, but as a side effect it loops, + // checking 'me' + clientSoc.setSoTimeout(1000); + + InputStream cin = clientSoc.getInputStream(); + cin.read(data, 0, data.length); + + receiveFromHostAddr = clientSoc.getInetAddress(); + receiveFromHostPort = clientSoc.getPort(); + + ByteArrayInputStream in = null; + in = new ByteArrayInputStream(data, 0, data.length); + item = new StreamPortItem(receiveFromHostAddr.getHostAddress(), + receiveFromHostPort, in); + } + return item; +} + +public void send(byte[] packet) throws IOException +{ + if (clientSoc != null) + { + OutputStream out = clientSoc.getOutputStream(); + out.write(packet); + out.flush(); + } +} + +public void close() +{ + try + { + if (clientSoc != null) + { + clientSoc.close(); + } + } + catch(IOException exc) {} + + try + { + if (serverSoc != null) + { + serverSoc.close(); + } + } + catch(IOException exc) {} + + serverSoc = null; + clientSoc = null; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/BlockPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/BlockPdu.java new file mode 100644 index 0000000..dfd650e --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/BlockPdu.java @@ -0,0 +1,402 @@ +// NAME +// $RCSfile: BlockPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.13 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + * The BlockPdu class is a wrapper class that will block until it + * receives the answer. + * + * @see Pdu + * + * @author Birgit Arkesteijn + * @version $Revision: 3.13 $ $Date: 2006/01/17 17:43:53 $ + */ +public class BlockPdu extends Object +{ + private static final String version_id = + "@(#)$Id: BlockPdu.java,v 3.13 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The GET PDU type. + */ + public final static int GET = 0; + /** + * The SET PDU type. + */ + public final static int SET = 1; + /** + * The GETNEXT PDU type. + */ + public final static int GETNEXT = 2; + /** + * The GETBULK PDU type. Note, the getBulkRequest was introduced in + * SNMPv2c. For that reason it should not be sent with SNMPv1. + */ + public final static int GETBULK = 3; + + protected Vector reqVarbinds; + private SnmpContextBasisFace context; + private Pdu pdu; + private int type = GET; + private int non_rep = 0; + private int max_rep = 0; + private int retry_intervals[] = null; + +/** + * Constructor. + * + * @param con The context of the request + */ +public BlockPdu(SnmpContextBasisFace con) +{ + context = con; + reqVarbinds = new Vector(1,1); +} + +/** + * Adds an OID to the PDU. + * + * @param oid The oid + * @see Pdu#addOid(String) + */ +public void addOid(String oid) +{ + varbind vb = new varbind(oid); + addOid(vb); +} + +/** + * Adds an OID to the PDU and the value that has to be set. + * This is only useful for the SET type. + * + * @param oid The oid + * @see SetPdu#addOid(String, AsnObject) + * @see #SET + */ +public void addOid(String oid, AsnObject val) +{ + varbind vb = new varbind(oid, val); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU and the value that has + * to be set. + * This is only useful for the SET type. + * + * @param oid The oid + * @param val The value + * @see Pdu#addOid(AsnObjectId, AsnObject) + * @see varbind + * @since 4_12 + */ +public void addOid(AsnObjectId oid, AsnObject val) +{ + varbind vb = new varbind(oid, val); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU. The OID indicates which + * MIB variable we request or which MIB variable should be set. + * + * @param oid The oid + * @see Pdu#addOid(AsnObjectId) + * @see varbind + * @since 4_12 + */ +public void addOid(AsnObjectId oid) +{ + varbind vb = new varbind(oid); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU. + * + * @param var The varbind + * @see #addOid(String) + */ +public void addOid(varbind var) +{ + reqVarbinds.addElement(var); +} + +/** + * Sets the getBulkRequest parameters. + * This is only useful for the GETBULK type. + * If these parameters are not set, they both default to zero. + * + * @param nr The non repeaters. + * @param mr The max repetitions. + * @see GetBulkPdu#setMaxRepetitions(int) + * @see GetBulkPdu#setNonRepeaters(int) + * @see #GETBULK + */ +public void setBulkParameters(int nr, int mr) +{ + non_rep = nr; + max_rep = mr; +} + +/** + * Adds a list of OIDs to the PDU. + * + * @param oids The OIDs to be added + */ +public void addOid(String[] oids) +{ + for (int i=0; i 0) + { + value = vars[0].getValue(); + } + return value; +} + +/** + * Sends the request and waits (blocks) for the response. Returns the + * values of the variable bindings in the response. If no response was + * received, this will be null. + * + * @return The values of the variable bindings in the response + * @see #sendAndWait() + */ +public AsnObject[] getResponseVariables() +throws PduException, java.io.IOException +{ + AsnObject[] values = null; + varbind[] vars = sendAndWait(); + if (vars != null) + { + values = new AsnObject[vars.length]; + for (int i=0; i 0) + { + var = vars[0]; + } + return var; +} + +/** + * Sends the request and waits (blocks) for the response. Returns the + * variable bindings in the response. If no response was received, this + * will be null. + * + * @return The variable bindings in the response + * @see #sendAndWait() + */ +public varbind[] getResponseVariableBindings() +throws PduException, java.io.IOException +{ + varbind[] vars = sendAndWait(); + return vars; +} + +/** + * Sends the request and waits (blocks) for the response. This is the core + * of the blocking getResponseVariableX() methods. + * + * @return The response, can be null if there was a timeout + * @see Pdu#send() + * @see Pdu#waitForSelf() + * @see Pdu#getResponseVarbinds() + */ +protected synchronized varbind[] sendAndWait() +throws PduException, java.io.IOException +{ + int sz = reqVarbinds.size(); + switch (type) + { + case SET: + { + pdu = new SetPdu_vec(context, sz); + break; + } + case GETNEXT: + { + pdu = new GetNextPdu_vec(context, sz); + break; + } + case GETBULK: + { + pdu = new GetBulkPdu(context); + ((GetBulkPdu)pdu).setNonRepeaters(non_rep); + ((GetBulkPdu)pdu).setMaxRepetitions(max_rep); + break; + } + default: + { + pdu = new GetPdu_vec(context, sz); + } + } + for (int i=0; iwww.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + * This class is used to perform the SNMPv3 USM discovery. + * This PDU cannot have any OIDs. + * + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * @author Birgit Arkesteijn + * @version $Revision: 3.15 $ $Date: 2006/11/29 16:12:50 $ + */ +public class DiscoveryPdu extends GetPdu +{ + private static final String version_id = + "@(#)$Id: DiscoveryPdu.java,v 3.15 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + private SnmpContextv3Face context; + +/** + * Constructor. + * + * @param cntxt The v3 context of the PDU + */ +public DiscoveryPdu(SnmpContextv3Face cntxt) +{ + super(cntxt); + context = cntxt; +} + +/** + * Cannot add any OID. This method is overwritten to prevent users from + * adding any OID. + * + * @exception IllegalArgumentException A discovery PDU cannot have any + * OID. + */ +public void addOid(String oid) +throws IllegalArgumentException +{ + throw new IllegalArgumentException("DiscoveryPdu cannot have OID"); +} + +/** + * Cannot add any OID. This method is overwritten to prevent users from + * adding any OID. + * + * @exception IllegalArgumentException A discovery PDU cannot have any + * OID. + * @since 4_12 + */ +public void addOid(String oid, AsnObject val) +{ + throw new IllegalArgumentException("DiscoveryPdu cannot have OID"); +} + +/** + * Cannot add any OID. This method is overwritten to prevent users from + * adding any OID. + * + * @exception IllegalArgumentException A discovery PDU cannot have any + * OID. + * @since 4_12 + */ +public void addOid(AsnObjectId oid, AsnObject val) +{ + throw new IllegalArgumentException("DiscoveryPdu cannot have OID"); +} + +/** + * Cannot add any OID. This method is overwritten to prevent users from + * adding any OID. + * + * @exception IllegalArgumentException A discovery PDU cannot have any + * OID. + */ +public void addOid(varbind var) +throws IllegalArgumentException +{ + throw new IllegalArgumentException("DiscoveryPdu cannot have OID"); +} + +/** + * Cannot add any OID. This method is overwritten to prevent users from + * adding any OID. + * + * @exception IllegalArgumentException A discovery PDU cannot have any + * OID. + * @since 4_12 + */ +public void addOid(AsnObjectId oid) +{ + throw new IllegalArgumentException("DiscoveryPdu cannot have OID"); +} + +/** + * Sends the PDU. + * Note that all properties of the context have to be set before this + * point. + */ +public boolean send() throws java.io.IOException, PduException +{ + if (added == false) + { + // Moved this statement from the constructor because it + // conflicts with the way the SnmpContextXPool works. + added = context.addDiscoveryPdu(this); + } + Enumeration vbs = reqVarbinds.elements(); + encodedPacket = context.encodeDiscoveryPacket(msg_type, getReqId(), + getErrorStatus(), getErrorIndex(), vbs, snmpv3MsgId); + addToTrans(); + return added; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/GetNextPdu_vec.java b/src/main/java/uk/co/westhawk/snmp/pdu/GetNextPdu_vec.java new file mode 100644 index 0000000..7c82778 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/GetNextPdu_vec.java @@ -0,0 +1,149 @@ +// NAME +// $RCSfile: GetNextPdu_vec.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.13 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.lang.*; + +/** + *

    + * The GetNextPdu_vec class will ask for a number of objects (OIDs), based + * on the GetNext request. + *

    + * + *

    + * Specify with addOid() the OIDs that should be requested with this + * PDU request. No more than count (see constructor) should be added. + * Add an Observer to the PDU with addObserver(), and send the PDU + * with send(). + *

    + * + *

    + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + * + * @author Birgit Arkesteijn + * @version $Revision: 3.13 $ $Date: 2006/11/29 16:12:50 $ + * @see Pdu#addOid + * @see Pdu#send + * @see InterfaceGetNextPdu + * @see OneGetNextPdu + * @see varbind + */ +public class GetNextPdu_vec extends GetNextPdu +{ + private static final String version_id = + "@(#)$Id: GetNextPdu_vec.java,v 3.13 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + varbind[] value; + + /** + * Constructor. + * + * @param con The context of the request + * @param count The number of OIDs to be get + */ + public GetNextPdu_vec(SnmpContextBasisFace con, int count) + { + super(con); + value = new varbind[count]; + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param var the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind var) + { + if (n + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + */ + protected void tell_them() + { + notifyObservers(value); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/GetPdu_vec.java b/src/main/java/uk/co/westhawk/snmp/pdu/GetPdu_vec.java new file mode 100644 index 0000000..5eb10bc --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/GetPdu_vec.java @@ -0,0 +1,148 @@ +// NAME +// $RCSfile: GetPdu_vec.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.13 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.lang.*; + +/** + *

    + * The GetPdu_vec class will ask for a number of objects (OIDs), based + * on the Get request. + *

    + * + *

    + * Specify with addOid() the OIDs that should be requested with this + * PDU request. No more than count (see constructor) should be added. + * Add an Observer to the PDU with addObserver(), and send the PDU + * with send(). + *

    + * + *

    + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + * + * @author Birgit Arkesteijn + * @version $Revision: 3.13 $ $Date: 2006/11/29 16:12:50 $ + * @see Pdu#addOid + * @see Pdu#send + * @see varbind + * @see OneIntPdu + */ +public class GetPdu_vec extends GetPdu +{ + private static final String version_id = + "@(#)$Id: GetPdu_vec.java,v 3.13 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + varbind[] value; + + /** + * Constructor. + * + * @param con The context of the request + * @param count The number of OIDs to be get + */ + public GetPdu_vec(SnmpContextBasisFace con, int count) + { + super(con); + value = new varbind[count]; + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param var the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind var) + { + if (n + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + */ + protected void tell_them() + { + notifyObservers(value); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/InformPdu_vec.java b/src/main/java/uk/co/westhawk/snmp/pdu/InformPdu_vec.java new file mode 100644 index 0000000..bca22b2 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/InformPdu_vec.java @@ -0,0 +1,142 @@ +// NAME +// $RCSfile: InformPdu_vec.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2002 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.lang.*; + +/** + *

    + * The InformPdu_vec class will inform a manager about a number of + * objects (OIDs), based on the Inform request. + *

    + * + *

    + * Specify with addOid() the OIDs that should be informed with this + * InformPdu request. No more than count (see constructor) + * should be added. + * Add an Observer to the InformPdu with addObserver(), and + * send the InformPdu with send(). + *

    + * + *

    + * Note, this PDU should be sent to port 162 (the default trap port) by + * default. You will have to create a SnmpContext with the + * ListeningContextFace.DEFAULT_TRAP_PORT as parameter! + *

    + * + *

    + * Inform Requests + * are sent between managers. It is a kind of 'acknowlegded' trap since + * the receiving end should send a Response Pdu as reply. + * The varbind list has the same elements as the TrapPduv2. + *

    + * + * @see Pdu#addOid + * @see Pdu#send + * @see varbind + * @see ListeningContextFace#DEFAULT_TRAP_PORT + * @since 4_12 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/11/29 16:12:50 $ + */ +public class InformPdu_vec extends InformPdu +{ + private static final String version_id = + "@(#)$Id: InformPdu_vec.java,v 3.5 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + varbind[] value; + +/** + * Constructor. + * + * @param con The context of the request + * @param count The number of OIDs to be get + */ +public InformPdu_vec(SnmpContextBasisFace con, int count) +{ + super(con); + value = new varbind[count]; +} + +/** + * The value of the request is set. This will be called by + * InformPdu.fillin(). + * + * @param n the index of the value + * @param var the value + * @see Pdu#new_value + */ +protected void new_value(int n, varbind var) +{ + if (n + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + */ +protected void tell_them() +{ + notifyObservers(value); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPdu.java new file mode 100644 index 0000000..bb669fb --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPdu.java @@ -0,0 +1,177 @@ +// NAME +// $RCSfile: InterfaceGetNextPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.17 $ +// CREATED +// $Date: 2008/05/06 10:17:06 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.util.*; + + +/** + * The class InterfaceGetNextPdu. + * + * This file is auto generated by the StubBrowser utility, using Mibble. + * See the uk/co/westhawk/stub/ directory. + * + * Added speed parameter and methods by hand. + + * Make sure that you replace the package name and classname placeholders. + * Also, move this file to the correct package directory. + * If these things are not done, this class will not compile correctly!! + * + * @version $Revision: 3.17 $ $Date: 2008/05/06 10:17:06 $ + */ +public class InterfaceGetNextPdu extends InterfaceGetNextPduStub +{ + private static final String version_id = + "@(#)$Id: InterfaceGetNextPdu.java,v 3.17 2008/05/06 10:17:06 birgita Exp $ Copyright Westhawk Ltd"; + + protected long _speed; + + +/** + * Constructor. + * + * @param con The context of the request + */ +public InterfaceGetNextPdu(SnmpContextBasisFace con) +{ + super(con); +} + + +/** + * Returns the last calculates speed. + * + * @see #getSpeed(InterfaceGetNextPdu) + */ +public long getSpeed() +{ + return _speed; +} + +/** + * Calculates the speed of the interface. This is done by providing the + * method with the previous value of this interface. An interface + * is marked by its index. Do not confuse it + * with the previous interface ifInOctets the MIB. + * Total number of octets (received and transmitted) per second. + * + * @param old The previous value of this interface + */ +public long getSpeed(InterfaceGetNextPdu old) +{ + _speed = -1; + if (this._ifOperStatus > 0 + && + old._ifOperStatus > 0 + && + this._valid + && + old._valid) + { + long tdiff = (this._sysUpTime - old._sysUpTime); + if (tdiff != 0) + { + long inO = this._ifInOctets - old._ifInOctets; + long outO = this._ifOutOctets - old._ifOutOctets; + + _speed = 100 * (inO + outO) / tdiff; + } + } + else + { + _speed = -1; + } + return _speed; +} + + +/** + * Returns how many interfaces are present. + * + * @return the number of interfaces + */ +public static int getIfNumber(SnmpContextBasisFace con) +throws PduException, java.io.IOException +{ + int ifNumber =0; + + if (con != null) + { + OneIntPdu ifNumberPdu = new OneIntPdu(con, ifNumber_OID + ".0"); + boolean answered = ifNumberPdu.waitForSelf(); + boolean timedOut = ifNumberPdu.isTimedOut(); + if (timedOut == false) + { + Integer intValue = ifNumberPdu.getValue(); + if (intValue != null) + { + ifNumber = intValue.intValue(); + } + } + } + return ifNumber; +} + + +public String toString() +{ + StringBuffer buffer = new StringBuffer(getClass().getName()); + buffer.append("["); + buffer.append(super.toString()); + buffer.append(", speed=").append(_speed); + buffer.append("]"); + return buffer.toString(); +} + + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPduStub.java b/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPduStub.java new file mode 100644 index 0000000..331cca3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/InterfaceGetNextPduStub.java @@ -0,0 +1,498 @@ +// NAME +// $RCSfile: InterfaceGetNextPduStub.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.4 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.pdu.*; +import java.util.*; + + +/** + * The class InterfaceGetNextPduStub. + * + * This file is auto generated by the StubBrowser utility, using Mibble. + * See the uk/co/westhawk/stub/ directory. + * + * Make sure that you replace the package name and classname placeholders. + * Also, move this file to the correct package directory. + * If these things are not done, this class will not compile correctly!! + * + * @version $Revision: 3.4 $ $Date: 2006/11/29 16:12:50 $ + * @since 4_14 + */ +public class InterfaceGetNextPduStub extends GetNextPdu +{ + private static final String version_id = + "@(#)$Id: InterfaceGetNextPduStub.java,v 3.4 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + public final static String sysUpTime_OID = "1.3.6.1.2.1.1.3"; + public final static String ifNumber_OID = "1.3.6.1.2.1.2.1"; + public final static String ifIndex_OID = "1.3.6.1.2.1.2.2.1.1"; + public final static String ifDescr_OID = "1.3.6.1.2.1.2.2.1.2"; + public final static String ifSpeed_OID = "1.3.6.1.2.1.2.2.1.5"; + public final static String ifOperStatus_OID = "1.3.6.1.2.1.2.2.1.8"; + public final static String ifInOctets_OID = "1.3.6.1.2.1.2.2.1.10"; + public final static String ifOutOctets_OID = "1.3.6.1.2.1.2.2.1.16"; + + public final static int NO_SCAL = 2; + public final static int NO_COL = 6; + public final static int NO_OID = NO_SCAL + NO_COL; + + + public final static String scal_oids[] = + { + sysUpTime_OID, + ifNumber_OID, + }; + + public final static String col_oids[] = + { + ifIndex_OID, + ifDescr_OID, + ifSpeed_OID, + ifOperStatus_OID, + ifInOctets_OID, + ifOutOctets_OID, + }; + + public final static String all_oids[] = + { + sysUpTime_OID, + ifNumber_OID, + ifIndex_OID, + ifDescr_OID, + ifSpeed_OID, + ifOperStatus_OID, + ifInOctets_OID, + ifOutOctets_OID, + }; + + + protected long _sysUpTime; + protected int _ifNumber; + protected int _ifIndex; + protected String _ifDescr; + protected long _ifSpeed; + protected HashMap _ifOperStatusMap = new HashMap(3); + protected int _ifOperStatus; + protected long _ifInOctets; + protected long _ifOutOctets; + + protected boolean _valid = false; + +/** + * Constructor. + * + * @param con The context of the request + */ +public InterfaceGetNextPduStub(SnmpContextBasisFace con) +{ + super(con); + _ifOperStatusMap.put(new Integer(3), "testing"); + _ifOperStatusMap.put(new Integer(1), "up"); + _ifOperStatusMap.put(new Integer(2), "down"); + + _valid = false; +} + +/** + * Constructor that will send the first request immediately. + * + * @param con The context of the request + * @param o the Observer that will be notified when the answer is + * received + */ +public InterfaceGetNextPduStub(SnmpContextBasisFace con, Observer o) +throws PduException, java.io.IOException +{ + this(con); + addOids(null); + if (o != null) + { + addObserver(o); + } + send(); +} + + +/** + * The method addOids is the basis for the GetNext functionality. + * + * If old is null, it initialises the varbinds from all_oids. + * If old is not null, it copies the column OIDs from the + * old InterfaceGetNextPduStub object. + * so the request continues where the previous one left. + * + * Note, the scalars and the columns OIDs are handled differently. The + * scalars are always copied from the original scal_oids, only the + * column OIDs are copied from the old + * InterfaceGetNextPduStub object. + */ +public void addOids(InterfaceGetNextPduStub old) +{ + if (old != null) + { + for (int i=0; iwww.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + + +/** + * The InterfacePdu class asks one interface for information, useful for admin + * purposes. + * See IF-MIB. + * + * @author Tim Panton + * @version $Revision: 3.19 $ $Date: 2006/11/29 16:12:50 $ + * @see InterfacesPdu + * + */ +public class InterfacePdu extends GetPdu +{ + private static final String version_id = + "@(#)$Id: InterfacePdu.java,v 3.19 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + // see rfc 2863 + + /** + * ifNumber - + * The number of network interfaces (regardless of their current state) + * present on this system. + */ + final static String IFNUMBER ="1.3.6.1.2.1.2.1.0"; + + /** + * sysUpTime - + * The time (in hundredths of a second) since the network management + * portion of the system was last re-initialized. + */ + final static String SYS_UPTIME ="1.3.6.1.2.1.1.3"; + + /** + * ifDescr - + * A textual string containing information about the + * interface. This string should include the name of + * the manufacturer, the product name and the version + * of the hardware interface. + */ + final static String DESCR ="1.3.6.1.2.1.2.2.1.2"; + + /** + * ifOperStatus - + * The current operational state of the interface. + * The testing(3) state indicates that no operational + * packets can be passed. + */ + final static String OPR_STATUS ="1.3.6.1.2.1.2.2.1.8"; + + /** + * ifInOctets - + * The total number of octets received on the + * interface, including framing characters. + */ + final static String IN_OCTETS ="1.3.6.1.2.1.2.2.1.10"; + + /** + * ifOutOctets - + * The total number of octets transmitted outOctets of the + * interface, including framing characters. + */ + final static String OUT_OCTETS ="1.3.6.1.2.1.2.2.1.16"; + + /** + * The current operational state is up + */ + final public static String UP = "up"; + /** + * The current operational state is down + */ + final public static String DOWN = "down"; + /** + * The current operational state is testing + */ + final public static String TESTING = "testing"; + /** + * The current operational state is unknown + */ + final public static String UNKNOWN = "unknown"; + + long sysUpTime; + int operStatus; + long inOctet; + long outOctet; + long speed; + int index; + String descr; + boolean valid = false; + + + +/** + * Constructor. + * It permits this package to create this PDU without data. + * + * @param con The context of the request + */ +InterfacePdu(SnmpContextBasisFace con) +{ + super(con); +} + +/** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param o the Observer that will be notified when the answer is received + * @param interf the index of the requested interface + */ +public InterfacePdu(SnmpContextBasisFace con, Observer o, int interf) +throws PduException, java.io.IOException +{ + super(con); + + addOids(interf); + if (o!=null) + { + addObserver(o); + } + index = interf; + send(); +} + +/** + * Returns the index of the interface. + * @return the index + */ +public int getIndex() +{ + return index; +} + +/** + * Returns the time (in hundredths of a second) since the network management + * portion of the system was last re-initialized. + */ +public long getSysUpTime() +{ + return sysUpTime; +} + +/** + * Returns the description of the interface. + * @return the description + */ +public String getDescription() +{ + return descr; +} + +/** + * Returns the operational state of the interface. + * @return the operational state + */ +public int getOperStatus() +{ + return operStatus; +} + +/** + * Returns the string representation of the operational state of the + * interface. + * @return the operational state as string + * @see #getOperStatus() + * @see #getOperStatusString(int) + */ +public String getOperStatusString() +{ + return getOperStatusString(operStatus); +} + +/** + * Returns the string representation of a operational state. + * @see #getOperStatusString() + */ +public String getOperStatusString(int status) +{ + String str = null; + switch (status) + { + case 1: + str = UP; + break; + case 2: + str = DOWN; + break; + case 3: + str = TESTING; + break; + default: + str = UNKNOWN; + } + return str; +} + +/** + * Returns the total number of octets received on the + * interface, including framing characters. + */ +public long getInOctet() +{ + return inOctet; +} + + /** + * Returns the total number of octets transmitted outOctets of the + * interface, including framing characters. + */ +public long getOutOctet() +{ + return outOctet; +} + +/** + * Calculates the speed of the interface. This is done by providing the + * method with the previous value of this interface. An interface + * is marked by its index. + * + * @param old The previous value of this interface + */ +public long getSpeed(InterfacePdu old) +{ + long speed = -1; + if ((this.operStatus <1) || (old.operStatus <1) + || + !this.valid || !old.valid) + { + return -1; + } + long tdif = (this.sysUpTime - old.sysUpTime); + if (tdif != 0) + { + speed = 100 *((this.inOctet - old.inOctet) + + (this.outOctet - old.outOctet))/ tdif; + } + return speed; +} + +void addOids(int interf) +{ + addOid(SYS_UPTIME+".0"); + addOid(DESCR+"."+interf); + addOid(OPR_STATUS+"."+interf); + addOid(IN_OCTETS+"."+interf); + addOid(OUT_OCTETS+"."+interf); +} + +/** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param res the value + * @see Pdu#new_value + */ +protected void new_value(int n, varbind res) +{ + AsnObject obj = res.getValue(); + if (getErrorStatus() == AsnObject.SNMP_ERR_NOERROR) + { + try + { + switch (n) + { + case 0: + sysUpTime = ((AsnUnsInteger) obj).getValue(); + break; + case 1: + descr = ((AsnOctets) obj).getValue(); + break; + case 2: + operStatus = ((AsnInteger) obj).getValue(); + break; + case 3: + inOctet = ((AsnUnsInteger) obj).getValue(); + break; + case 4: + outOctet = ((AsnUnsInteger) obj).getValue(); + valid = true; + break; + default: + valid = false; + } + } + catch(ClassCastException exc) + { + sysUpTime = 0; + descr = null; + operStatus = 0; + inOctet = 0; + outOctet = 0; + valid = false; + } + } + else + { + valid = false; + } +} + +/** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + */ +protected void tell_them() +{ + notifyObservers(this); +} + +/** + * Returns how many interfaces are present. + * + * @return the number of interfaces + */ +public static int getNumIfs(SnmpContextBasisFace con) +throws PduException, java.io.IOException +{ + int ifCount =0; + + if (con != null) + { + OneIntPdu numIfs = new OneIntPdu(con, IFNUMBER); + boolean answered = numIfs.waitForSelf(); + boolean timedOut = numIfs.isTimedOut(); + if (answered == true && timedOut == false) + { + ifCount = numIfs.getValue().intValue(); + } + } + return ifCount; +} + + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/InterfacesPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/InterfacesPdu.java new file mode 100644 index 0000000..57540cb --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/InterfacesPdu.java @@ -0,0 +1,135 @@ +// NAME +// $RCSfile: InterfacesPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.12 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + * The InterfacesPdu class will ask for the number of current interfaces. + * For each interface it will send an InterfacePdu to get the + * information of the specific interface. + * + * @see InterfacePdu + * + * @author Tim Panton + * @version $Revision: 3.12 $ $Date: 2006/11/29 16:12:50 $ + * + */ +public class InterfacesPdu extends InterfacePdu +{ + private static final String version_id = + "@(#)$Id: InterfacesPdu.java,v 3.12 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * ifNumber + * The number of network interfaces (regardless of their current state) + * present on this system. + */ + final static String IFNUMBER ="1.3.6.1.2.1.2.1.0"; + + InterfacePdu [] ifs; + + +/** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param o the Observer that will be notified when the answer is received + * @param interfs the index of the requested interface + */ +public InterfacesPdu(SnmpContextBasisFace con, Observer o, int interfs) +throws PduException, java.io.IOException +{ + super(con); + ifs = new InterfacePdu [interfs]; + for (int interf=0; interf < interfs; interf++) + { + addOids(interf); + ifs[interf] = new InterfacePdu(con); + } + if (o!=null) + { + addObserver(o); + } + send(); +} + + +/** + * Returns the interfaces. + * + * @return the interfaces as an array of InterfacePdu + */ +public InterfacePdu [] getInterfacePdus() +{ + return ifs; +} + +/** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param res the value + * @see Pdu#new_value + */ +protected void new_value(int n, varbind res) +{ + int thif = n / 4; + if (thif < ifs.length) + { + ifs[thif].new_value(n%4,res); + } +} + + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneGetBulkPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetBulkPdu.java new file mode 100644 index 0000000..34d4fd8 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetBulkPdu.java @@ -0,0 +1,147 @@ +// NAME +// $RCSfile: OneGetBulkPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneGetBulkPdu class performs a getBulkRequest and collects + * the response varbinds into a Vector. + *

    + * + *

    + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an Vector of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + * + *

    + * For SNMPv3: The receiver of a request PDU acts as the authoritative engine. + *

    + * + * @see varbind + * @see Vector + * + * @author Birgit Arkesteijn + * @version $Revision: 3.9 $ $Date: 2006/01/17 17:43:53 $ + */ +public class OneGetBulkPdu extends GetBulkPdu +{ + private static final String version_id = + "@(#)$Id: OneGetBulkPdu.java,v 3.9 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The GetBulk request is the only request that will return more + * variables than you've sent. + */ + Vector vars; + +/** + * Constructor. + * + * @param con The context (v2c or v3) of the PDU + */ +public OneGetBulkPdu(SnmpContextBasisFace con) +{ + super(con); + vars = new Vector(); +} + + +/** + * Returns a vector with the response varbinds. + */ +public Vector getVarbinds() +{ + return vars; +} + + +/** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param a_var the value + * @see Pdu#new_value + */ +protected void new_value(int n, varbind a_var) +{ + if (n == 0) + { + vars = new Vector(); + } + vars.addElement(a_var); +} + +/** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an Vector of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + * + * @see Vector + */ +protected void tell_them() +{ + notifyObservers(vars); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneGetNextPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetNextPdu.java new file mode 100644 index 0000000..47e29d0 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetNextPdu.java @@ -0,0 +1,158 @@ +// NAME +// $RCSfile: OneGetNextPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2006/01/17 17:49:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneGetNextPdu class will ask for one (1) object (oid), based on + * the GetNext request. + *

    + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + * + *

    + * For SNMPv3: The receiver of a request PDU acts as the authoritative engine. + *

    + * + * @see varbind + * @see InterfaceGetNextPdu + * @see GetNextPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 3.14 $ $Date: 2006/01/17 17:49:53 $ + */ +public class OneGetNextPdu extends GetNextPdu +{ + private static final String version_id = + "@(#)$Id: OneGetNextPdu.java,v 3.14 2006/01/17 17:49:53 birgit Exp $ Copyright Westhawk Ltd"; + + varbind var; + + /** + * Constructor. + * + * @param con The context of the request + */ + public OneGetNextPdu(SnmpContextBasisFace con) + { + super(con); + } + + /** + * Constructor that will send the request immediately. No Observer + * is set. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + */ + public OneGetNextPdu(SnmpContextBasisFace con, String oid) + throws PduException, java.io.IOException + { + this(con, oid, null); + } + + /** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param o the Observer that will be notified when the answer is received + */ + public OneGetNextPdu(SnmpContextBasisFace con, String oid, Observer o) + throws PduException, java.io.IOException + { + super(con); + if (o != null) + { + addObserver(o); + } + addOid(oid); + send(); + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param a_var the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind a_var) + { + if (n == 0) + { + var = a_var; + } + } + + /** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + */ + protected void tell_them() + { + notifyObservers(var); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneGetPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetPdu.java new file mode 100644 index 0000000..325fbc6 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneGetPdu.java @@ -0,0 +1,156 @@ +// NAME +// $RCSfile: OneGetPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.13 $ +// CREATED +// $Date: 2006/01/17 17:49:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneGetPdu class will ask for one (1) object (OID), based on + * the Get request. + *

    + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + * + *

    + * For SNMPv3: The receiver of a request PDU acts as the authoritative engine. + *

    + * + * @see varbind + * + * @author Birgit Arkesteijn + * @version $Revision: 3.13 $ $Date: 2006/01/17 17:49:53 $ + */ +public class OneGetPdu extends GetPdu +{ + private static final String version_id = + "@(#)$Id: OneGetPdu.java,v 3.13 2006/01/17 17:49:53 birgit Exp $ Copyright Westhawk Ltd"; + + varbind var; + + /** + * Constructor. + * + * @param con The context of the request + */ + public OneGetPdu(SnmpContextBasisFace con) + { + super(con); + } + + /** + * Constructor that will send the request immediately. No Observer + * is set. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + */ + public OneGetPdu(SnmpContextBasisFace con, String oid) + throws PduException, java.io.IOException + { + this(con, oid, null); + } + + /** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param o the Observer that will be notified when the answer is received + */ + public OneGetPdu(SnmpContextBasisFace con, String oid, Observer o) + throws PduException, java.io.IOException + { + super(con); + if (o != null) + { + addObserver(o); + } + addOid(oid); + send(); + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param a_var the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind a_var) + { + if (n == 0) + { + var = a_var; + } + } + + /** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + */ + protected void tell_them() + { + notifyObservers(var); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneInformPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneInformPdu.java new file mode 100644 index 0000000..0538ca6 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneInformPdu.java @@ -0,0 +1,166 @@ +// NAME +// $RCSfile: OneInformPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/02/09 14:20:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2002 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneInformPdu class will inform a manager about one + * object (OIDs), based on the Inform request. + *

    + * + *

    + * This class represents the SNMP Inform Request PDU. Inform Requests + * are sent between managers. It is a kind of 'acknowlegded' trap since + * the receiving end should send a Response PDU as reply. + * The varbind list has the same elements as the TrapPduv2. + *

    + * + *

    + * Note, this PDU should be sent to port 162 (the default trap port) by + * default. You will have to create a SnmpContext with the + * ListeningContextFace.DEFAULT_TRAP_PORT as parameter! + *

    + * + *

    + * For SNMPv3: The receiver of an inform PDU acts as the authoritative engine. + *

    + * + * @deprecated As of 4_14, just use {@link InformPdu} + * @see InformPdu_vec + * @see varbind + * @see ListeningContextFace#DEFAULT_TRAP_PORT + * @since 4_12 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/02/09 14:20:09 $ + */ +public class OneInformPdu extends InformPdu +{ + private static final String version_id = + "@(#)$Id: OneInformPdu.java,v 3.5 2006/02/09 14:20:09 birgit Exp $ Copyright Westhawk Ltd"; + + varbind var; + +/** + * Constructor. + * + * @param con The context (v2c or v3) of the PDU + */ +public OneInformPdu(SnmpContextBasisFace con) +{ + super(con); +} + +/** + * Constructor that will send the request immediately. No Observer + * is set. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + */ +public OneInformPdu(SnmpContextBasisFace con, String oid) +throws PduException, java.io.IOException +{ + this(con, oid, null); +} + +/** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param o the Observer that will be notified when the answer is received + */ +public OneInformPdu(SnmpContextBasisFace con, String oid, Observer o) +throws PduException, java.io.IOException +{ + super(con); + if (o != null) + { + addObserver(o); + } + addOid(oid); + send(); +} + +/** + * The value of the request is set. This will be called by + * InformPdu.fillin(). + * + * @param n the index of the value + * @param a_var the value + * @see Pdu#new_value + */ +protected void new_value(int n, varbind a_var) +{ + if (n == 0) + { + var = a_var; + } +} + +/** + * This method notifies all observers. + * This will be called by InformPdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + */ +protected void tell_them() +{ + notifyObservers(var); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneIntPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneIntPdu.java new file mode 100644 index 0000000..53884e8 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneIntPdu.java @@ -0,0 +1,189 @@ +// NAME +// $RCSfile: OneIntPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneIntPdu class will ask for one (1) object (oid) of the + * AsnInteger type, based on the Get request. + *

    + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be an Integer. + * In the case of an exception, that exception will be passed. + *

    + * + *

    + * For SNMPv3: The receiver of a request PDU acts as the authoritative engine. + *

    + * + * @see GetPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 3.14 $ $Date: 2006/11/29 16:12:50 $ + */ +public class OneIntPdu extends GetPdu +{ + private static final String version_id = + "@(#)$Id: OneIntPdu.java,v 3.14 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + Integer value; + + /** + * Constructor. + * + * @param con The context of the request + */ + public OneIntPdu(SnmpContextBasisFace con) + { + super(con); + } + + /** + * Constructor that will send the request immediately. No Observer + * is set. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + */ + public OneIntPdu(SnmpContextBasisFace con, String oid) + throws PduException, java.io.IOException + { + this(con, oid, null); + } + + /** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param o the Observer that will be notified when the answer is received + */ + public OneIntPdu(SnmpContextBasisFace con, String oid, Observer o) + throws PduException, java.io.IOException + { + super(con); + if (o != null) + { + addObserver(o); + } + addOid(oid); + send(); + } + + + /** + * Returns the value (the answer) of this request. + * + * @return the value + */ + public Integer getValue() + { + return value; + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param res the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind res) + { + AsnObject val = res.getValue(); + if (val instanceof AsnInteger) + { + AsnInteger va = (AsnInteger) res.getValue(); + if (n == 0) + { + value = new Integer(va.getValue()); + } + } + else + { + value = null; + } + } + + /** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be an Integer. + * In the case of an exception, that exception will be passed. + *

    + */ + protected void tell_them() + { + notifyObservers(value); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneSetPdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneSetPdu.java new file mode 100644 index 0000000..cdc68b7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneSetPdu.java @@ -0,0 +1,164 @@ +// NAME +// $RCSfile: OneSetPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2006/01/17 17:49:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + *

    + * The OneSetPdu class will set the value of one (1) object (oid), based + * on the Set request. + *

    + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + * + *

    + * For SNMPv3: The receiver of a request PDU acts as the authoritative engine. + *

    + * + * @deprecated As of 4_14, just use {@link SetPdu} + * @see varbind + * @see SetPdu_vec + * + * @author Birgit Arkesteijn + * @version $Revision: 3.14 $ $Date: 2006/01/17 17:49:53 $ + */ +public class OneSetPdu extends SetPdu +{ + private static final String version_id = + "@(#)$Id: OneSetPdu.java,v 3.14 2006/01/17 17:49:53 birgit Exp $ Copyright Westhawk Ltd"; + + varbind var; + + /** + * Constructor. + * + * @param con The context of the request + */ + public OneSetPdu(SnmpContextBasisFace con) + { + super(con); + } + + /** + * Constructor that will send the request immediately. No Observer + * is set. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param val The value + */ + public OneSetPdu(SnmpContextBasisFace con, String oid, AsnObject val) + throws PduException, java.io.IOException + { + this(con, oid, val, null); + } + + /** + * Constructor that will send the request immediately. + * + * @param con the SnmpContextBasisFace + * @param oid the oid + * @param val The value + * @param o the Observer that will be notified when the answer is received + */ + public OneSetPdu(SnmpContextBasisFace con, String oid, AsnObject val, Observer o) + throws PduException, java.io.IOException + { + super(con); + if (o != null) + { + addObserver(o); + } + addOid(oid, val); + send(); + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). This is the value of the OID after the Set request + * was done. If the SNMP server allowed the set, this will be the + * same value as was set in SetPdu.addOid(). + * + * @param n the index of the value + * @param a_var the value + * @see Pdu#new_value + * @see SetPdu#addOid(String, AsnObject) + */ + protected void new_value(int n, varbind a_var) + { + if (n == 0) + { + var = a_var; + } + } + + /** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a varbind, so any AsnObject type can be returned. + * In the case of an exception, that exception will be passed. + *

    + */ + protected void tell_them() + { + notifyObservers(var); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv1.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv1.java new file mode 100644 index 0000000..5f289af --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv1.java @@ -0,0 +1,94 @@ +// NAME +// $RCSfile: OneTrapPduv1.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.7 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.util.*; +import java.io.*; + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.util.*; + +/** + * This class represents the ASN SNMPv1 Trap PDU object. + * See RFC1157-SNMP. + * + * @deprecated As of 4_14, just use {@link TrapPduv1} + * @author Birgit Arkesteijn + * @version $Revision: 3.7 $ $Date: 2006/03/23 14:54:09 $ + */ +public class OneTrapPduv1 extends TrapPduv1 +{ + private static final String version_id = + "@(#)$Id: OneTrapPduv1.java,v 3.7 2006/03/23 14:54:09 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param con The context v1 of the OneTrapPduv1 + * @see SnmpContext + */ +public OneTrapPduv1(SnmpContext con) +{ + super(con); +} + +/** + * Constructor. + * + * @param con The context v1 of the OneTrapPduv1 + * @see SnmpContext + */ +public OneTrapPduv1(SnmpContextPool con) +{ + super(con); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv2.java b/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv2.java new file mode 100644 index 0000000..9d6da04 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/OneTrapPduv2.java @@ -0,0 +1,88 @@ +// NAME +// $RCSfile: OneTrapPduv2.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.util.*; +import java.io.*; + +import uk.co.westhawk.snmp.stack.*; +import uk.co.westhawk.snmp.util.*; + +/** + * This class represents the ASN SNMPv2c (and higher) Trap PDU object. + * See RFC1157-SNMP. + * + *

    + * For SNMPv3: The sender of a trap PDU acts as the authoritative engine. + *

    + * + * @deprecated As of 4_14, just use {@link TrapPduv2} + * @author Birgit Arkesteijn + * @version $Revision: 3.9 $ $Date: 2006/03/23 14:54:09 $ + */ +public class OneTrapPduv2 extends TrapPduv2 +{ + private static final String version_id = + "@(#)$Id: OneTrapPduv2.java,v 3.9 2006/03/23 14:54:09 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param con The context (v2c, v3) of the OneTrapPduv2 + * @see SnmpContext + */ +public OneTrapPduv2(SnmpContextBasisFace con) +{ + super(con); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv1.java b/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv1.java new file mode 100644 index 0000000..6c1018a --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv1.java @@ -0,0 +1,107 @@ +// NAME +// $RCSfile: PassiveTrapPduv1.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.7 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// ERG Group Ltd +// TO DO +// + +/* + * Copyright (C) 2002 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; + +/** + * This class represents the ASN SNMP v1 Trap PDU object + * that does not create a thread to send itself. It must be used with the + * context class PassiveSnmpContext. The original purpose of the + * Passive classes is to allow the stack to be used in environments where + * thread creation is unwanted, eg database JVMs such as Oracle JServer. + * See SNMPv2-PDU. + * + *

    + * See + * notes + * on how to send traps in an Oracle JServer environment. + *

    + * + * @see PassiveTrapPduv2 + * @since 4_12 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.7 $ $Date: 2006/03/23 14:54:09 $ + */ +public class PassiveTrapPduv1 extends TrapPduv1 +{ + private static final String version_id = + "@(#)$Id: PassiveTrapPduv1.java,v 3.7 2006/03/23 14:54:09 birgit Exp $ Copyright ERG Group Ltd"; + +/** + * Constructor. + * + * @param con The context (v1) of the PDU. + * This is of type PassiveSnmpContext to ensure that the correct threading + * behaviour occurs. + */ +public PassiveTrapPduv1(PassiveSnmpContext con) +{ + super(con); + + // this makes the base class PDU believe that the trap is already + // awaiting transmission therefore it does not create a transmitter + // for this pdu + added = true; +} + +/** + * Override of the operation in PDU. Send the trap in the + * callers thread. That is, don't create a sending thread + * or add it to a queue or anything, just go straight to the socket. + */ +public void addToTrans() +{ + sendme(); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv2.java b/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv2.java new file mode 100644 index 0000000..30fb59c --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/PassiveTrapPduv2.java @@ -0,0 +1,107 @@ +// NAME +// $RCSfile: PassiveTrapPduv2.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.8 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// ERG Group Ltd +// TO DO +// + +/* + * Copyright (C) 2001 by ERG Group Ltd + * www.erggroup.com + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Mike Waters + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; + +/** + * This class represents the ASN SNMP v2c (and higher) Trap PDU object + * that does not create a thread to send itself. It must be used with the + * context class PassiveSnmpContextv2c. The original purpose of the + * Passive classes is to allow the stack to be used in environments where + * thread creation is unwanted, eg database JVMs such as Oracle JServer. + * See SNMPv2-PDU. + * + *

    + * See + * notes + * on how to send traps in an Oracle JServer environment. + *

    + * + * @see PassiveTrapPduv1 + * @since 4_12 + * + * @author Mike Waters, ERG Group + * @version $Revision: 3.8 $ $Date: 2006/03/23 14:54:09 $ + */ +public class PassiveTrapPduv2 extends TrapPduv2 +{ + private static final String version_id = + "@(#)$Id: PassiveTrapPduv2.java,v 3.8 2006/03/23 14:54:09 birgit Exp $ Copyright ERG Group Ltd"; + +/** + * Constructor. + * + * @param con The context (v2c) of the PDU. + * This is of type PassiveSnmpContextv2c to ensure that the correct threading + * behaviour occurs. + */ +public PassiveTrapPduv2(PassiveSnmpContextv2c con) +{ + super(con); + + // this makes the base class PDU believe that the trap is already + // awaiting transmission therefore it does not create a transmitter + // for this pdu + added = true; +} + +/** + * Override of the operation in PDU. Send the trap in the + * callers thread. That is, don't create a sending thread + * or add it to a queue or anything, just go straight to the socket. + */ +public void addToTrans() +{ + sendme(); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/SetPdu_vec.java b/src/main/java/uk/co/westhawk/snmp/pdu/SetPdu_vec.java new file mode 100644 index 0000000..e75eaac --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/SetPdu_vec.java @@ -0,0 +1,138 @@ +// NAME +// $RCSfile: SetPdu_vec.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.lang.*; + +/** + *

    + * The SetPdu_vec class will set the value of a number of + * objects (OIDs), based on the Set request. + *

    + * + *

    + * Specify with addOid() the OIDs that should be requested with this + * PDU request. No more than count (see constructor) should be added. + * Add an Observer to the PDU with addObserver(), and send the PDU + * with send(). + *

    + * + *

    + * If no exception occurred whilst receiving the response, the Object to the + * update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. + * If an exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + * + * @see SetPdu#addOid + * @see Pdu#send + * @see varbind + * @see OneSetPdu + * + * @author Birgit Arkesteijn + * @version $Revision: 3.14 $ $Date: 2006/11/29 16:12:50 $ + */ +public class SetPdu_vec extends SetPdu +{ + private static final String version_id = + "@(#)$Id: SetPdu_vec.java,v 3.14 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + varbind[] value; + + /** + * Constructor. + * + * @param con The context of the request + * @param count The number of OIDs to be get + */ + public SetPdu_vec(SnmpContextBasisFace con, int count) + { + super(con); + value = new varbind[count]; + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). These are the values of the OIDs after the Set request + * was done. If the SNMP server allowed the sets, these will be the + * same values as was set in SetPdu.addOid(). + * + * @param n the index of the value + * @param var the value + * @see Pdu#new_value + * @see SetPdu#addOid(String, AsnObject) + */ + protected void new_value(int n, varbind var) + { + if (n + * If no exception occurred whilst receiving the response, the + * Object to the update() method of the Observer will be an array of + * varbinds, so they may contains any AsnObject type. If an + * exception occurred, that exception will be passed as the Object + * to the update() method. + *

    + */ + protected void tell_them() + { + notifyObservers(value); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/pdu/UpSincePdu.java b/src/main/java/uk/co/westhawk/snmp/pdu/UpSincePdu.java new file mode 100644 index 0000000..d808e01 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/pdu/UpSincePdu.java @@ -0,0 +1,149 @@ +// NAME +// $RCSfile: UpSincePdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.16 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.pdu; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.stack.*; +import java.util.*; + +/** + * The UpSincePdu class will send a Get request for the sysUpTime and + * will calculate that date the system rebooted the last time. + * + * @author Tim Panton + * @version $Revision: 3.16 $ $Date: 2006/11/29 16:12:50 $ + */ +public class UpSincePdu extends GetPdu +{ + private static final String version_id = + "@(#)$Id: UpSincePdu.java,v 3.16 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + Date since; + /** + * The oid of sysUpTime + */ + public final static String SYSUPTIME="1.3.6.1.2.1.1.3.0"; + + /** + * Constructor that will send the request immediately. + * + * @param con The context of the request + * @param o the Observer that will be notified when the answer is received + */ + public UpSincePdu(SnmpContextBasisFace con, Observer o) + throws PduException, java.io.IOException + { + super(con); + addOid(SYSUPTIME); + if (o != null) + { + addObserver(o); + } + send(); + } + + + /** + * Returns the date when the system went up, (sysUpTime). + * @return the date + */ + public Date getDate() + { + return since; + } + + /** + * The value of the request is set. This will be called by + * Pdu.fillin(). + * + * @param n the index of the value + * @param res the value + * @see Pdu#new_value + */ + protected void new_value(int n, varbind res) + { + // given the uptime in centi seconds and the time now, + // calculate the time it rebooted + + AsnObject val = res.getValue(); + if (val instanceof AsnUnsInteger) + { + AsnUnsInteger va = (AsnUnsInteger) res.getValue(); + if (n == 0) + { + long value = va.getValue(); + Date now = new Date(); + long then = now.getTime(); + then -= 10 * value; + since = new Date(then); + } + } + else + { + since = null; + } + } + + /** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * Unless an exception occurred the Object to the update() method of the + * Observer will be a Date. + * In the case of an exception, that exception will be passed. + *

    + */ + protected void tell_them() + { + notifyObservers(since); + } + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AbstractSnmpContext.java b/src/main/java/uk/co/westhawk/snmp/stack/AbstractSnmpContext.java new file mode 100644 index 0000000..6eadaa9 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AbstractSnmpContext.java @@ -0,0 +1,1009 @@ +// NAME +// $RCSfile: AbstractSnmpContext.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.33 $ +// CREATED +// $Date: 2009/03/05 12:48:04 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; +import uk.co.westhawk.snmp.net.*; +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.util.*; + +/** + * This class contains the abstract SNMP context that is needed by every + * Pdu to send a SNMP v1, v2c or v3 request. + * The context also provides functionality to receive PDUs. + * + *

    + * destroy() should be called when the context is no longer + * used. This is the only way the threads will be stopped and garbage + * collected. + *

    + * + * @see SnmpContext + * @see SnmpContextv2c + * @see SnmpContextv3 + * + * @author Tim Panton + * @version $Revision: 3.33 $ $Date: 2009/03/05 12:48:04 $ + */ +public abstract class AbstractSnmpContext extends Object + implements SnmpContextBasisFace, Runnable, RawPduListener +{ + private static final String version_id = + "@(#)$Id: AbstractSnmpContext.java,v 3.33 2009/03/05 12:48:04 birgita Exp $ Copyright Westhawk Ltd"; + + private ContextSocketFace soc; + private Transmitter [] transmitters; + private Pdu [] pdus; + private Thread me; + private String basename; + private volatile boolean stopRequested; + // thanks to Nick Sheen nsheen@tippingpoint.com for pointing out that volatile is needed here + + protected String typeSocket; + protected String hostname; + protected String bindAddr; + protected int hostPort; + protected int maxRecvSize; + protected boolean isDestroyed; + protected boolean anyPduExpectingResponse = false; + protected RequestPduReceivedSupport pduSupport; + protected TrapReceivedSupport trapSupport; + + +/** + * Processes an incoming response. Has to be overload by each context. + * This is called in the run() method. + * + * @see #run + */ +protected abstract void processIncomingResponse(ByteArrayInputStream in) +throws DecodingException, IOException; + +/** + * Encodes a PDU. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * Has to be overload by each context. + * + * @param msg_type The message type + * @param rId The message id + * @param errstat The error status + * @param errind The error index + * @param ve The varbind list + * @param obj Additional object (only used in SNMPv3) + * @return The encoded packet + */ +public abstract byte[] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws IOException, EncodingException; + +/** + * Processes an incoming pdu (but not a response). Has to be overload by each context. + * @see #rawPduReceived + */ +public abstract Pdu processIncomingPdu(byte [] message) throws DecodingException, IOException; + +/** + * Returns the SNMP version of this context. Has to be overload by each + * context. + */ +public abstract int getVersion(); + +/** + * Constructor. + * The Standard socket type will be used. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +protected AbstractSnmpContext(String host, int port) throws IOException +{ + this(host, port, null, STANDARD_SOCKET); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +protected AbstractSnmpContext(String host, int port, String typeSocketA) +throws IOException +{ + this(host, port, null, typeSocketA); +} + +/** + * Constructor. + * + * If bindAddress is null, then the system will pick up a valid local + * address to bind the socket. + * + * The typeSocket will indicate which type of socket to use. This way + * different handlers can be provided. + * It should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @exception IOException Thrown when the socket cannot be + * created. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +protected AbstractSnmpContext(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + pdus = new Pdu[MAXPDU]; + hostname = host; + hostPort = port; + bindAddr = bindAddress; + typeSocket = typeSocketA; + transmitters = new Transmitter[MAXPDU]; + basename = host+"_"+ port+"_"+bindAddress; + trapSupport = new TrapReceivedSupport(this); + pduSupport = new RequestPduReceivedSupport(this); + + isDestroyed = false; + stopRequested = false; + maxRecvSize = MSS; + + soc = getSocket(typeSocket); + if (soc != null) + { + soc.create(hostname, hostPort, bindAddr); + if (AsnObject.debug > 12) + { + System.out.println(getClass().getName() + + ": soc.getLocalSocketAddress() = " + + soc.getLocalSocketAddress()); + System.out.println(getClass().getName() + + ": soc.getRemoteSocketAddress() = " + + soc.getRemoteSocketAddress()); + } + } +} + + +/** + * Returns a new socket, based on a particular type. + * Parameter type is first compare do STANDARD_SOCKET and TCP_SOCKET. If + * that doesn't match, type is assumed to be a fully qualified classname. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +static ContextSocketFace getSocket(String type) throws IOException +{ + ContextSocketFace sf = null; + if (type != null) + { + String className = null; + if (type.equals(STANDARD_SOCKET)) + { + className = "uk.co.westhawk.snmp.net.StandardSocket"; + } + else if (type.equals(TCP_SOCKET)) + { + className = "uk.co.westhawk.snmp.net.TCPSocket"; + } + else + { + className = type; + } + + try + { + Class cl = Class.forName(className); + Object obj = cl.newInstance(); + sf = (ContextSocketFace) obj; + } + catch (ClassNotFoundException exc) + { + String str = "AbstractSnmpContext.getSocket(): ClassNotFound problem " + exc.getMessage() + ", type=" + type; + throw (new IOException(str)); + } + catch (InstantiationException exc) + { + String str = "AbstractSnmpContext.getSocket(): Instantiation problem " + exc.getMessage() + ", type=" + type; + throw (new IOException(str)); + } + catch (IllegalAccessException exc) + { + String str = "AbstractSnmpContext.getSocket(): IllegalAccess problem " + exc.getMessage() + ", type=" + type; + throw (new IOException(str)); + } + catch (ClassCastException exc) + { + String str = "AbstractSnmpContext.getSocket(): ClassCast problem " + exc.getMessage() + ", type=" + type; + throw (new IOException(str)); + } + + if (sf == null) + { + String str = "AbstractSnmpContext.getSocket(): Cannot create socket " + type; + throw (new IOException(str)); + } + else + { + if (AsnObject.debug > 12) + { + System.out.println("AbstractSnmpContext.getSocket(): New socket " + sf.getClass().getName()); + } + } + } + return sf; +} + +public String getHost() +{ + return hostname; +} + +/** + * Returns the IP address string + * aaa.bbb.ccc.ddd (IPv4) or a:b:c:d:e:f:g:h (IPv6) + * of the host. + * + * @return The IP address of the host + * @deprecated As of 4_14, use {@link #getSendToHostAddress()} + */ +public String getHostAddress() +{ + return getSendToHostAddress(); +} + +public String getSendToHostAddress() +{ + String res = ""; + if (soc != null) + { + res = soc.getSendToHostAddress(); + } + return res; +} + +public String getReceivedFromHostAddress() +{ + String res = ""; + if (soc != null) + { + res = soc.getReceivedFromHostAddress(); + } + return res; +} + + +public int getPort() +{ + return hostPort; +} + +public String getBindAddress() +{ + return bindAddr; +} + +public String getTypeSocket() +{ + return typeSocket; +} + +/** + * Returns the maximum number of bytes this context will read from the + * socket. By default this will be set to MSS (i.e. 1300). + * + * @since 4_12 + * @see SnmpContextBasisFace#MSS + * @see #setMaxRecvSize(int) + * @return The number + */ +public int getMaxRecvSize() +{ + return maxRecvSize; +} + +/** + * Sets the maximum number of bytes this context will read from the + * socket. By default this will be set to MSS (i.e. 1300). + * The default size seems a reasonable size. The problem usually occurs + * when sending Bulk requests. + * + *

    + * If a packet arrives that is bigger than the maximum size of received + * bytes, the stack will try to decode it nevertheless. The usual + * error that will occur is: + *

    + *
    + * Error message: "Incorrect packet. No of bytes received less than packet length."
    + * 
    + * + *

    + * Although UDP datagrams can be fragmented (fragmentation is part of + * the network layer (IP), not the transport layer (UDP/TCP)), some + * firewalls reject incoming fragments. Therefor it is best not to set + * maxRecvSize higher than the largest packet size you can get through + * your network topology. + *

    + * + *

    + * Thanks to Pete Kazmier (pete@kazmier.com) for the suggestion. + *

    + * + * + * Note, this property is NOT supported in any of the SNMPContextXXPool + * classes. + * + * + * @since 4_12 + * @see SnmpContextBasisFace#MSS + * @see #getMaxRecvSize() + * @param no The new number + */ +public void setMaxRecvSize(int no) +{ + maxRecvSize = no; +} + +/** + * Returns the thread usage of the AbstractSnmpContext. + * It returns a String in the form of =PO=QR--------------0. + * + *

    + * The String represents the array of transmitters. + * Each character represents a transmitter slot. + * The transmitters form a thread pool of a maximum size, MAXPDU. + * Each transmitter is used to wait for one PDU response at a given + * moment in time. + * When the response is received the transmitter will stop running, but + * is not destroyed. It will be reused. + *

    + * + *

    + * Meaning of each character: + *

    + *
      + *
    • - a transmitter slot has not yet been allocated a thread
    • + *
    • = there is a thread but it is idle
    • + *
    • A->Z the thread is transmitting a Pdu
    • + *
    • + * The last character represents the context's recv thread: + *
        + *
      • 0 there isn't one
      • + *
      • 1 it exists but isn't running
      • + *
      • 2 it exists and is alive.
      • + *
      + *
    • + *
    + * + * @since 4_12 + * @return The thread usage of the AbstractSnmpContext + */ +public String getDebugString() +{ + char [] cret = new char[MAXPDU+1]; + for (int i=0;i + * It closes the socket. + * The thread will actually stop/finish when the run() finishes. Since + * the socket is closed, the run() will fall through almost instantly. + *

    + * + *

    + * Note: The thread(s) will not die immediately; this will take about + * half a minute. + *

    + * + * @see ListeningContext#destroy() + * @see ListeningContextPool#destroyPool() + */ +public synchronized void destroy() +{ + if (isDestroyed == false) + { + stopRequested = true; + if (AsnObject.debug > 12) + { + System.out.println(getClass().getName() + ".destroy(): Closing socket "); + } + soc.close(); + isDestroyed = true; + + // If run() has been started, then it will destroy the + // transmitter threads when it finishes. Otherwise they must be + // destroyed here. + if (me == null) + { + freeTransmitters(); + } + } +} + +public boolean isDestroyed() +{ + return isDestroyed; +} + +/** + * This method will stop the thread. + * All transmitters, PDUs in flight and traplisteners will be removed + * when run() finishes. + *

    + * It does NOT close the socket. + * The thread will actually stop/finish when the run() finishes. That is when + * a packet arrives on the socket or when the socket times out. + *

    + * + *

    + * We have deprecated this method since there is no point in stopping + * the context, but not destroying it. The context cannot start again anyway. + * The difference between destroy() and stop() was not very clear. + *

    + * + * @deprecated As of version 4_12, should use {@link #destroy()} + * @see #destroy() + */ +public synchronized void stop() +{ + stopRequested = true; +} + +/** + * We wait for any incoming packets. After receiving one, decode + * the packet into an Pdu. The Pdu will notify the observers waiting + * for an response. + * + *

    + * Thanks to Chris Barlock <barlock@us.ibm.com> who reported a + * NullPointerException in run() on variable 'me' and introduced the + * variable stopRequested. + *

    + */ +public void run() +{ + // while It is visible + while (!stopRequested) + { + // block for incoming packets + me.yield(); + try + { + if (stopRequested) + { + break; + } + + StreamPortItem item = soc.receive(maxRecvSize); + ByteArrayInputStream in = item.getStream(); + + if (AsnObject.debug > 10) + { + int nb = in.available(); + byte [] bu = new byte[nb]; + in.read(bu); + in.reset(); + + SnmpUtilities.dumpBytes(getClass().getName() + + ".run(): Received from " + + item.getHostAddress() + + ", from port " + item.getHostPort() + + ": ", bu); + } + processIncomingResponse(in); + } + catch (IOException exc) + { + if (exc instanceof InterruptedIOException) + { + if (AsnObject.debug > 15) + { + System.out.println(getClass().getName() + ".run(): Idle recv " + exc.getMessage()); + } + } + else if (exc instanceof java.net.SocketException) + { + if (AsnObject.debug > 15) + { + System.out.println(getClass().getName() + ".run(): SocketException " + exc.getMessage()); + } + } + else + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".run(): " + + exc.getClass().getName() + " " + exc.getMessage()); + exc.printStackTrace(); + } + } + } + catch (DecodingException exc) + { + if (AsnObject.debug > 1) + { + System.out.println(getClass().getName() + ".run(): DecodingException: " + exc.getMessage()); + } + } + catch (Exception exc) + { + if (AsnObject.debug > 1) + { + System.out.println(getClass().getName() + ".run(): Exception: " + exc.getMessage()); + exc.printStackTrace(); + } + } + catch (Error err) + { + if (AsnObject.debug > 1) + { + System.out.println(getClass().getName() + ".run(): Error: " + err.getMessage()); + err.printStackTrace(); + } + } + } + + freeTransmitters(); + + trapSupport.empty(); + pduSupport.empty(); + + // This used to actually create a listener. I do think this bug + // has been fixed, since no socket will be created in + // ListeningContextPool, unless a listener has been added. + ListeningContextPool lcontext = + new ListeningContextPool(ListeningContextFace.DEFAULT_TRAP_PORT, bindAddr, typeSocket); + lcontext.removeRawPduListenerFromPool(this); + + me = null; + soc = null; +} + + + +/* + * By moving activate() from the constructor to here, the parameter + * maxRecvSize, changed in setMaxRecvSize(), gets a chance to actually + * change before run() starts. + * Thanks to Dave Hunt who reported this + * problem. + */ +public synchronized void sendPacket(byte[] p) +{ + if (isDestroyed == false) + { + activate(); + try + { + if (AsnObject.debug > 10) + { + SnmpUtilities.dumpBytes("Sending to " + + soc.getSendToHostAddress() + ": ", p); + } + + // Seen it throw an "java.io.IOException: Invalid argument" + // when the bind address was wrong, i.e. the packet reach + // the host over the interface + soc.send(p); + } + catch (IOException exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".sendPacket(): " + + exc.getClass().getName() + + " " + exc.getMessage()); + exc.printStackTrace(); + } + } + } +} + +Pdu getPdu(Integer ReqId) +{ + return getPdu(ReqId.intValue()); +} + +Pdu getPdu(int rid) +{ + Pdu ret = null; + for (int i=0; i< MAXPDU; i++) + { + if ((pdus[i] != null) && (pdus[i].getReqId() == rid)) + { + ret = pdus[i]; + break; + } + } + return ret; +} + +public synchronized boolean removePdu(int rid) +{ + boolean ret = false; + for (int i=0; i< MAXPDU; i++) + { + if ((pdus[i] != null) && (pdus[i].getReqId() == rid)) + { + pdus[i] = null; + ret = true; + break; + } + } + return ret; +} + +public synchronized boolean addPdu(Pdu p) +throws IOException, PduException +{ + boolean done = false; + if (isDestroyed == true) + { + throw new EncodingException("Context can no longer be used, since it is already destroyed"); + } + else + { + // I only want to start the receive thread when any of the + // context's PDUs is actually expecting a response. See activate(). + if (anyPduExpectingResponse == false) + { + anyPduExpectingResponse = p.isExpectingResponse(); + } + for (int i=0; i 2) + { + System.out.println(getClass().getName() + ".rawPduReceived(): DecodingException: " + exc.getMessage()); + } + } + catch(IOException exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".rawPduReceived(): IOException "+ exc.getMessage()); + } + } + + } + else + { + if (AsnObject.debug > 5) + { + System.out.println(getClass().getName() + ".rawPduReceived(): " + + "Pdu host (" + hostAddress + + "), does not correspond with context host (" + + this.getSendToHostAddress() + ")"); + } + } + } + else + { + if (AsnObject.debug > 5) + { + String theirs = SnmpUtilities.getSnmpVersionString(version); + String ours = SnmpUtilities.getSnmpVersionString(this.getVersion()); + System.out.println(getClass().getName() + ".rawPduReceived(): " + + "Pdu version " + theirs + + ", does not correspond with context version " + + ours); + } + } +} + +Transmitter getTrans(int i) +{ + if (transmitters[i] == null) + { + transmitters[i] = new Transmitter(basename+"_v"+getVersion()+"_Trans"+i); + } + return transmitters[i]; +} + +/** + * Creates and starts the Receive thread that allows this context to + * receive packets. + * Subclasses may override this to adjust the threading behaviour. + * + * @see PassiveSnmpContext#activate() + * @see PassiveSnmpContextv2c#activate() + */ +protected void activate() +{ + // Only start the thread when 'me' is null (i.e. no thread is running) + // AND when anyPduExpectingResponse is true. + // This way a context that only sends (for example) traps, will not + // start a listing thread. + if (me == null && anyPduExpectingResponse == true) + { + me = new Thread(this, basename+"_v"+getVersion()+"_Receive"); + me.setPriority(me.MAX_PRIORITY); + me.start(); + } +} + + +/** + * Frees the transmitters. + * + * @see #run() + * @see #destroy() + * @since 5_1 + */ +// In version 5_0, this code lived in run(). +// Thanks to Vincent Deconinck +protected void freeTransmitters() +{ + for (int i=0;iwww.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * Thrown to indicate that the response PDU was received OK, but the PDU + * contains an error. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/01/17 17:43:54 $ + */ +public class AgentException extends PduException +{ + private static final String version_id = + "@(#)$Id: AgentException.java,v 3.5 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructs an AgentException with no specified detail message. + * + */ +public AgentException() +{ + super(); +} + +/** + * Constructs an AgentException with the specified detail + * message. + * + * @param str The detail message. + */ +public AgentException(String str) +{ + super(str); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderBase.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderBase.java new file mode 100644 index 0000000..37beb03 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderBase.java @@ -0,0 +1,174 @@ +// NAME +// $RCSfile: AsnDecoderBase.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2007/10/17 10:36:47 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the general methods to decode bytes into a Pdu. + * We split the original class AsnDecoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.3 $ $Date: 2007/10/17 10:36:47 $ + */ +class AsnDecoderBase extends Object +{ + private static final String version_id = + "@(#)$Id: AsnDecoderBase.java,v 3.3 2007/10/17 10:36:47 birgita Exp $ Copyright Westhawk Ltd"; + +/** + * Reads the input into an asn sequence. + */ +AsnSequence getAsnSequence(InputStream in) +throws IOException, DecodingException +{ + AsnSequence asnTopSeq = null; + AsnSequence dummy = new AsnSequence(); + AsnObject obj = dummy.AsnReadHeader(in); + if (obj instanceof AsnSequence) + { + asnTopSeq = (AsnSequence) obj; + } + else + { + String msg = "AsnSequence was expected"; + if (obj != null) + { + msg += " instead of " + obj.getRespTypeString(); + } + else + { + msg += ", but is null"; + } + throw new DecodingException(msg); + } + return asnTopSeq; +} + +/** + * Returns the SNMP version number of the asn sequence. + */ +int getSNMPVersion(AsnSequence asnTopSeq) throws DecodingException +{ + int version = -1; + AsnObject obj = asnTopSeq.getObj(0); + if (obj instanceof AsnInteger) + { + AsnInteger v = (AsnInteger) obj; + version = v.getValue(); + } + else + { + String msg = "SNMP version should be of type AsnInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return version; +} + +/** + * Returns the SNMP v1 and v2c community of the asn sequence. + */ +String getCommunity(AsnSequence asnTopSeq) throws DecodingException +{ + String comm =""; + AsnObject obj = asnTopSeq.getObj(1); + if (obj instanceof AsnOctets) + { + AsnOctets estat = (AsnOctets) obj; + comm = estat.getValue(); + } + else + { + String msg = "community should be of type AsnOctets" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return comm; +} + + +AsnSequence getAsnHeaderData(AsnSequence asnTopSeq) throws DecodingException +{ + AsnSequence asnHeaderData = null; + AsnObject obj = asnTopSeq.getObj(1); + if (obj instanceof AsnSequence) + { + asnHeaderData = (AsnSequence) obj; + } + else + { + String msg = "asnHeaderData should be of type AsnSequence" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return asnHeaderData; +} + + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv1.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv1.java new file mode 100644 index 0000000..9a4c680 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv1.java @@ -0,0 +1,112 @@ +// NAME +// $RCSfile: AsnDecoderv1.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/02/09 14:16:36 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v1 specific methods to decode bytes into a Pdu. + * We split the original class AsnDecoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.3 $ $Date: 2006/02/09 14:16:36 $ + */ +class AsnDecoderv1 extends AsnDecoderBase +{ + private static final String version_id = + "@(#)$Id: AsnDecoderv1.java,v 3.3 2006/02/09 14:16:36 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * This method creates an AsnPduSequence or an AsnTrapPduv1Sequence out of + * the characters of the InputStream for v1. + * + * @see AbstractSnmpContext#run + * @see SnmpContext#processIncomingResponse + * @see SnmpContext#processIncomingPdu + */ +AsnSequence DecodeSNMP(InputStream in, String community) +throws IOException, DecodingException +{ + AsnSequence asnTopSeq = getAsnSequence(in); + int snmpVersion = getSNMPVersion(asnTopSeq); + if (snmpVersion != SnmpConstants.SNMP_VERSION_1) + { + String str = SnmpUtilities.getSnmpVersionString(snmpVersion); + String msg = "Wrong SNMP version: expected SNMPv1, received " + + str; + throw new DecodingException(msg); + } + String comm = getCommunity(asnTopSeq); + if (comm.equals(community) == false) + { + String msg = "Wrong community: expected " + + community + ", received " + comm; + throw new DecodingException(msg); + } + + // The message is either a 'normal' PDU or a Trap v1 PDU. + AsnSequence seqPdu = null; + seqPdu = (AsnPduSequence) asnTopSeq.findPdu(); + if (seqPdu == null) + { + seqPdu = (AsnTrapPduv1Sequence) asnTopSeq.findTrapPduv1(); + } + return seqPdu; +} + + + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv2c.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv2c.java new file mode 100644 index 0000000..e6bb033 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv2c.java @@ -0,0 +1,117 @@ +// NAME +// $RCSfile: AsnDecoderv2c.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/02/09 14:16:36 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v2c specific methods to decode bytes into a Pdu. + * We split the original class AsnDecoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.3 $ $Date: 2006/02/09 14:16:36 $ + */ +class AsnDecoderv2c extends AsnDecoderBase +{ + private static final String version_id = + "@(#)$Id: AsnDecoderv2c.java,v 3.3 2006/02/09 14:16:36 birgit Exp $ Copyright Westhawk Ltd"; + + + +/** + * This method creates an AsnPduSequence out of the characters of the + * InputStream for v2c. + * + * @see AbstractSnmpContext#run + * @see SnmpContextv2c#processIncomingResponse + * @see SnmpContextv2c#processIncomingPdu + */ +AsnPduSequence DecodeSNMPv2c(InputStream in, String community) +throws IOException, DecodingException +{ + AsnSequence asnTopSeq = getAsnSequence(in); + int snmpVersion = getSNMPVersion(asnTopSeq); + if (snmpVersion != SnmpConstants.SNMP_VERSION_2c) + { + String str = SnmpUtilities.getSnmpVersionString(snmpVersion); + String msg = "Wrong SNMP version: expected SNMPv2c, received " + + str; + throw new DecodingException(msg); + } + String comm = getCommunity(asnTopSeq); + if (comm.equals(community) == false) + { + String msg = "Wrong community: expected " + + community + ", received " + comm; + throw new DecodingException(msg); + } + AsnPduSequence Pdu = (AsnPduSequence) asnTopSeq.findPdu(); + return Pdu; +} + + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv3.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv3.java new file mode 100644 index 0000000..0a34fdc --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnDecoderv3.java @@ -0,0 +1,497 @@ +// NAME +// $RCSfile: AsnDecoderv3.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2009/03/05 12:48:59 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v3 specific methods to decode bytes into a Pdu. + * We split the original class AsnDecoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.9 $ $Date: 2009/03/05 12:48:59 $ + */ +class AsnDecoderv3 extends AsnDecoderBase implements usmStatsConstants +{ + private static final String version_id = + "@(#)$Id: AsnDecoderv3.java,v 3.9 2009/03/05 12:48:59 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Returns the msgId of the SNMPv3 asn sequence. + */ +int getMsgId(AsnSequence asnTopSeq) throws DecodingException +{ + int msgId = -1; + AsnSequence asnHeaderData = getAsnHeaderData(asnTopSeq); + AsnObject obj = asnHeaderData.getObj(0); + if (obj instanceof AsnInteger) + { + AsnInteger value = (AsnInteger) obj; + msgId = value.getValue(); + } + else + { + String msg = "msgId should be of type AsnInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return msgId; +} + +/** + * This method creates an AsnPduSequence out of the characters of the + * InputStream for v3. + * + * @see AbstractSnmpContext#run + * @see SnmpContextv3#processIncomingResponse + * @see SnmpContextv3#processIncomingPdu + */ +AsnSequence DecodeSNMPv3(InputStream in) +throws IOException, DecodingException +{ + AsnSequence asnTopSeq = getAsnSequence(in); + int snmpVersion = getSNMPVersion(asnTopSeq); + if (snmpVersion != SnmpConstants.SNMP_VERSION_3) + { + String str = SnmpUtilities.getSnmpVersionString(snmpVersion); + String msg = "Wrong SNMP version: expected SNMPv3, received " + + str; + throw new DecodingException(msg); + } + else + { + int securityModel = -1; + AsnSequence asnHeaderData = getAsnHeaderData(asnTopSeq); + AsnObject obj = asnHeaderData.getObj(3); + if (obj instanceof AsnInteger) + { + AsnInteger value = (AsnInteger) obj; + securityModel = value.getValue(); + if (securityModel != SnmpContextv3Face.USM_Security_Model) + { + String msg = "Wrong v3 Security Model: expected USM(" + + SnmpContextv3Face.USM_Security_Model + + "), received " + + securityModel; + throw new DecodingException(msg); + } + } + else + { + String msg = "securityModel should be of type AsnInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + } + return asnTopSeq; +} + + +/** + * Processes the SNMP v3 AsnSequence. + * See section 3.2 of SNMP-USER-BASED-SM-MIB. + */ +AsnPduSequence processSNMPv3(SnmpContextv3Basis context, AsnSequence asnTopSeq, byte[] message, boolean amIAuthoritative) +throws IOException, DecodingException +{ + AsnPduSequence pduSeq = null; + + // if not correct, I'll just skip a lot of tests. + boolean isCorrect = asnTopSeq.isCorrect; + + AsnSequence asnHeaderData = getAsnHeaderData(asnTopSeq); + //int msgId = ((AsnInteger)asnHeaderData.getObj(0)).getValue(); + //int maxSize = ((AsnInteger)asnHeaderData.getObj(1)).getValue(); + byte [] msgFlags = ((AsnOctets)asnHeaderData.getObj(2)).getBytes(); + boolean isUseAuthentication = isUseAuthentication(msgFlags[0]); + boolean isUsePrivacy = isUsePrivacy(msgFlags[0]); + + AsnOctets asnSecurityParameters = (AsnOctets)asnTopSeq.getObj(2); + AsnSequence usmObject = decodeUSM(asnSecurityParameters); + + byte [] engineIdBytes = ((AsnOctets)usmObject.getObj(0)).getBytes(); + String engineId = SnmpUtilities.toHexString(engineIdBytes); + int boots = ((AsnInteger)usmObject.getObj(1)).getValue(); + int time = ((AsnInteger)usmObject.getObj(2)).getValue(); + String userName = ((AsnOctets)usmObject.getObj(3)).getValue(); + AsnOctets realFingerPrintObject = (AsnOctets)usmObject.getObj(4); + byte [] realFingerPrint = realFingerPrintObject.getBytes(); + byte [] salt = ((AsnOctets)usmObject.getObj(5)).getBytes(); + + TimeWindow tWindow = TimeWindow.getCurrent(); + if (amIAuthoritative == false) + { + /* engineId should not be empty, however net-snmp 5.3.0.1 has a + * bug (1427410) in their trapsess; it sends an empty engineId + */ + if (engineId.length() > 0 + && + tWindow.isEngineIdOK(context.getReceivedFromHostAddress(), + context.getPort(), engineId) == false) + { + String msg = "Received engine Id ('" + engineId + "') is not correct."; + msg += " amIAuthoritative == false"; + throw new DecodingException(msg); + } + else + { + // This should only happen once, if for some reason the sendto + // and receivedfrom addresses are different. + // It is a hack, but it needs to seem like the 'sendToHostAddress' + // has been discovered, else any other request sent to this + // address will try to do another discovery and the process + // starts again. + String sendToHostAddress = context.getSendToHostAddress(); + String receivedFromHostAddress = context.getReceivedFromHostAddress(); + if (sendToHostAddress.equals(receivedFromHostAddress) == false) + { + String storedEngineId; + storedEngineId = tWindow.getSnmpEngineId(sendToHostAddress, context.getPort()); + if (storedEngineId == null) + { + tWindow.setSnmpEngineId(sendToHostAddress, context.getPort(), "00"); + } + } + } + } + else + { + // amIAuthoritative == true + // Section 3.2 rfc + // engineId of length '0' -> discovery. + if (engineId.length() > 0 + && + tWindow.isEngineIdOK(context.getUsmAgent().MYFAKEHOSTNAME, + context.getPort(), engineId) == false) + { + String msg = "Received engine Id ('" + engineId + "') is not correct."; + msg += " amIAuthoritative == true"; + throw new DecodingException(msg); + } + } + + if (userName.equals(context.getUserName()) == false) + { + String msg = "Received userName ('" + userName + "') is not correct"; + throw new DecodingException(msg); + } + + // I'm not really supposed to encrypt before checking and doing + // authentication, but I would like to use the pduSeq + // So, I'll encrypt and save the possible exception. + DecodingException encryptionDecodingException = null; + IOException encryptionIOException = null; + try + { + AsnObject asnScopedObject = asnTopSeq.getObj(3); + AsnSequence asnPlainScopedPdu = null; + if (isUsePrivacy == true) + { + // if decryption was used, the asnScopedObject would be AsnOctets + byte[] privKey = null; + int prot = context.getAuthenticationProtocol(); + if (prot == context.MD5_PROTOCOL) + { + byte[] passwKey = context.getPrivacyPasswordKeyMD5(); + privKey = SnmpUtilities.getLocalizedKeyMD5(passwKey, engineId); + } + else + { + byte[] passwKey = context.getPrivacyPasswordKeySHA1(); + privKey = SnmpUtilities.getLocalizedKeySHA1(passwKey, engineId); + } + + AsnOctets asnEncryptedScopedPdu = (AsnOctets)asnScopedObject; + byte[] encryptedText = asnEncryptedScopedPdu.getBytes(); + + byte[] plainText = null; + int pprot = context.getPrivacyProtocol(); + if (pprot == context.AES_ENCRYPT) + { + plainText = SnmpUtilities.AESdecrypt(encryptedText, + privKey, boots, time, salt); + } + else + { + plainText = SnmpUtilities.DESdecrypt(encryptedText, + salt, privKey); + } + + if (AsnObject.debug > 10) + { + System.out.println("Encrypted PDU: "); + System.out.println("Decoding with : "+context.ProtocolNames[pprot]); + } + + ByteArrayInputStream plainIn = new ByteArrayInputStream(plainText); + asnPlainScopedPdu = getAsnSequence(plainIn); + } + else + { + asnPlainScopedPdu = (AsnSequence)asnScopedObject; + } + + byte [] contextId = ((AsnOctets)asnPlainScopedPdu.getObj(0)).getBytes(); + String contextName = ((AsnOctets)asnPlainScopedPdu.getObj(1)).getValue(); + pduSeq = (AsnPduSequence) asnPlainScopedPdu.findPdu(); + } + catch (DecodingException exc) + { + encryptionDecodingException = exc; + } + catch (IOException exc) + { + encryptionIOException = exc; + } + if (pduSeq != null && engineId.length() == 0) + { + pduSeq.setSnmpv3Discovery(true); + } + + boolean userIsUsingAuthentication = context.isUseAuthentication(); + if (isCorrect == true && (isUseAuthentication != userIsUsingAuthentication)) + { + String msg = "User " + userName + " does "; + if (userIsUsingAuthentication == false) + { + msg += "not "; + } + msg += "support authentication, but received message "; + + if (isUseAuthentication) + { + msg += "with authentication."; + } + else + { + msg += "without authentication"; + msg += getUsmStats(pduSeq); + } + throw new DecodingException(msg); + } + + boolean isAuthentic = false; + if (isCorrect == true && isUseAuthentication == true) + { + int fpPos = realFingerPrintObject.getContentsPos(); + if (AsnObject.debug > 10) + { + int fpLength = realFingerPrintObject.getContentsLength(); + String str = "Pos finger print = " + fpPos + + ", len = " + fpLength; + SnmpUtilities.dumpBytes(str, realFingerPrint); + } + + byte[] calcFingerPrint = null; + // Replace the real finger print with the dummy finger print + System.arraycopy(AsnEncoderv3.dummyFingerPrint, 0, + message, fpPos, realFingerPrint.length); + int prot = context.getAuthenticationProtocol(); + if (prot == context.MD5_PROTOCOL) + { + byte[] passwKey = context.getAuthenticationPasswordKeyMD5(); + byte[] authkey = SnmpUtilities.getLocalizedKeyMD5(passwKey, + engineId); + calcFingerPrint = SnmpUtilities.getFingerPrintMD5(authkey, + message); + } + else + { + byte[] passwKey = context.getAuthenticationPasswordKeySHA1(); + byte[] authkey = SnmpUtilities.getLocalizedKeySHA1(passwKey, + engineId); + calcFingerPrint = SnmpUtilities.getFingerPrintSHA1(authkey, + message); + } + + if (SnmpUtilities.areBytesEqual(realFingerPrint, calcFingerPrint) == false) + { + String msg = "Authentication comparison failed"; + throw new DecodingException(msg); + } + else + { + if (pduSeq != null && boots == 0 && time == 0) + { + pduSeq.setSnmpv3Discovery(true); + } + if (tWindow.isOutsideTimeWindow(engineId, boots, time)) + { + String msg = "Message is outside time window"; + throw new DecodingException(msg); + } + isAuthentic = true; + } + } + tWindow.updateTimeWindow(engineId, boots, time, isAuthentic); + + boolean userIsUsingPrivacy = context.isUsePrivacy(); + if (isCorrect == true && (isUsePrivacy != userIsUsingPrivacy)) + { + String msg = "User " + userName + " does "; + if (userIsUsingPrivacy == false) + { + msg += "not "; + } + msg += "support privacy, but received message "; + if (isUsePrivacy) + { + msg += "with privacy."; + } + else + { + msg += "without privacy"; + msg += getUsmStats(pduSeq); + } + throw new DecodingException(msg); + } + + if (encryptionDecodingException != null) + { + throw encryptionDecodingException; + } + if (encryptionIOException != null) + { + throw encryptionIOException; + } + + if (pduSeq != null && isCorrect == false) + { + pduSeq.isCorrect = false; + } + return pduSeq; +} + + +private boolean isUseAuthentication(byte msgFlags) +{ + boolean isUseAuthentication = ((byte)(0x01) & msgFlags) > 0; + return isUseAuthentication; +} + + +private boolean isUsePrivacy(byte msgFlags) +{ + boolean isUsePrivacy = ((byte)(0x02) & msgFlags) > 0; + return isUsePrivacy; +} + + +private AsnSequence decodeUSM(AsnOctets asnSecurityParameters) +throws IOException +{ + byte [] usmBytes = asnSecurityParameters.getBytes(); + if (AsnObject.debug > 10) + { + SnmpUtilities.dumpBytes("Decoding USM:", usmBytes); + } + + ByteArrayInputStream usmIn = new ByteArrayInputStream(usmBytes); + AsnSequence usmOctets = new AsnSequence(usmIn, usmBytes.length, + asnSecurityParameters.getContentsPos()); + AsnSequence usmObject = (AsnSequence)usmOctets.getObj(0); + return usmObject; +} + + +/** + * Sometimes when an error occurs the usmStats is sent in the varbind + * list. + */ +private String getUsmStats(AsnPduSequence pduSeq) +{ + String msg = ""; + AsnSequence varBind = (AsnSequence) pduSeq.getObj(3); + int size = varBind.getObjCount(); + if (size > 0) + { + AsnSequence varSeq = (AsnSequence) varBind.getObj(0); + varbind vb = new varbind(varSeq); + AsnObjectId oid = vb.getOid(); + boolean found=false; + int i=0; + while (i< usmStatsOids.length && found==false) + { + AsnObjectId usmOid = new AsnObjectId(usmStatsOids[i]); + found = (oid.startsWith(usmOid) == true); + i++; + } + if (found == true) + { + i--; + msg += ": " + usmStatsStrings[i] + " " + vb.getValue(); + } + else + { + msg += ": " + vb; + } + } + return msg; +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderBase.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderBase.java new file mode 100644 index 0000000..1d0f670 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderBase.java @@ -0,0 +1,115 @@ +// NAME +// $RCSfile: AsnEncoderBase.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.2 $ +// CREATED +// $Date: 2006/01/17 17:43:53 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the general methods to encode a Pdu into bytes. + * We split the original class AsnEncoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.2 $ $Date: 2006/01/17 17:43:53 $ + */ +class AsnEncoderBase extends Object +{ + private static final String version_id = + "@(#)$Id: AsnEncoderBase.java,v 3.2 2006/01/17 17:43:53 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Encode PDU itself packet into bytes. + * The actual PDU encoding is the same for v1 to v3. + * Except for Trapv1, but we are not implementing that. + */ +protected AsnObject EncodePdu(byte msg_type, + int pduId, int errstat, int errind, Enumeration ve) + throws IOException +{ + AsnObject asnPduObject, asnVBObject; + + // kind of request + asnPduObject = new AsnSequence(msg_type); + asnPduObject.add(new AsnInteger(pduId)); // reqid + asnPduObject.add(new AsnInteger(errstat)); // errstat + asnPduObject.add(new AsnInteger(errind)); // errindex + + // Create VarbindList sequence + AsnObject asnVBLObject = asnPduObject.add(new AsnSequence()); + + // Add variable bindings + while (ve.hasMoreElements()) + { + asnVBObject = asnVBLObject.add(new AsnSequence()); + varbind vb = (varbind) ve.nextElement(); + asnVBObject.add(vb.getOid()); + asnVBObject.add(vb.getValue()); + } + + return asnPduObject; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv1.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv1.java new file mode 100644 index 0000000..e23228b --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv1.java @@ -0,0 +1,184 @@ +// NAME +// $RCSfile: AsnEncoderv1.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/02/09 14:16:36 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v1 specific methods to encode a Pdu into bytes. + * We split the original class AsnEncoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.3 $ $Date: 2006/02/09 14:16:36 $ + */ +class AsnEncoderv1 extends AsnEncoderBase +{ + private static final String version_id = + "@(#)$Id: AsnEncoderv1.java,v 3.3 2006/02/09 14:16:36 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Encode SNMPv1 Trap packet into bytes. + */ +ByteArrayOutputStream EncodeSNMP(SnmpContext context, byte msg_type, + String enterprise, byte[] IpAddress, int generic_trap, int + specific_trap, long timeTicks, Enumeration ve) + throws IOException, EncodingException +{ + ByteArrayOutputStream bout; + AsnSequence asnTopSeq; + + // Create authentication + asnTopSeq = new AsnSequence(); + asnTopSeq.add(new AsnInteger(SnmpConstants.SNMP_VERSION_1)); + asnTopSeq.add(new AsnOctets(context.getCommunity())); // community + + // Create PDU sequence. + AsnObject asnPduObject = EncodeTrap1Pdu(msg_type, enterprise, + IpAddress, generic_trap, specific_trap, timeTicks, ve); + + asnTopSeq.add(asnPduObject); + + if (AsnObject.debug > 10) + { + System.out.println("\n" + getClass().getName() + ".EncodeSNMP(): "); + } + // Write SNMP object + bout = new ByteArrayOutputStream(); + asnTopSeq.write(bout); + return bout; +} + +/** + * Encode Trapv1 PDU itself packet into bytes. + */ +private AsnObject EncodeTrap1Pdu(byte msg_type, + String enterprise, byte[] IpAddress, int generic_trap, int + specific_trap, long timeTicks, Enumeration ve) + throws IOException +{ + AsnObject asnPduObject, asnVBObject; + + // kind of request + asnPduObject = new AsnSequence(msg_type); + asnPduObject.add(new AsnObjectId(enterprise)); // enterprise + + // agent-addr (thanks Donnie Love (dlove@idsonline.com) for + // pointing out that we should have used IPADDRESS type) + asnPduObject.add(new AsnOctets(IpAddress, AsnObject.IPADDRESS)); + + asnPduObject.add(new AsnInteger(generic_trap)); // generic-trap + asnPduObject.add(new AsnInteger(specific_trap)); // specific-trap + asnPduObject.add(new AsnUnsInteger(timeTicks)); // time-stap + + // Create VarbindList sequence + AsnObject asnVBLObject = asnPduObject.add(new AsnSequence()); + + // Add variable bindings + while (ve.hasMoreElements()) + { + asnVBObject = asnVBLObject.add(new AsnSequence()); + varbind vb = (varbind) ve.nextElement(); + asnVBObject.add(vb.getOid()); + asnVBObject.add(vb.getValue()); + } + + return asnPduObject; +} + + +/** + * Encode SNMPv1 packet into bytes. + */ +ByteArrayOutputStream EncodeSNMP(SnmpContext context, byte msg_type, + int pduId, int errstat, int errind, Enumeration ve) + throws IOException, EncodingException +{ + ByteArrayOutputStream bout; + AsnSequence asnTopSeq; + + // Create authentication + asnTopSeq = new AsnSequence(); + asnTopSeq.add(new AsnInteger(AsnObject.SNMP_VERSION_1)); + asnTopSeq.add(new AsnOctets(context.getCommunity())); // community + + // Create PDU sequence. + AsnObject asnPduObject = EncodePdu(msg_type, pduId, errstat, errind, ve); + asnTopSeq.add(asnPduObject); + + if (AsnObject.debug > 10) + { + System.out.println("\n" + getClass().getName() + ".EncodeSNMP(): "); + } + // Write SNMP object + bout = new ByteArrayOutputStream(); + asnTopSeq.write(bout); + return bout; +} + + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv2c.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv2c.java new file mode 100644 index 0000000..c7878d9 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv2c.java @@ -0,0 +1,113 @@ +// NAME +// $RCSfile: AsnEncoderv2c.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/02/09 14:16:36 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v2c specific methods to encode a Pdu into bytes. + * We split the original class AsnEncoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.3 $ $Date: 2006/02/09 14:16:36 $ + */ +class AsnEncoderv2c extends AsnEncoderBase +{ + private static final String version_id = + "@(#)$Id: AsnEncoderv2c.java,v 3.3 2006/02/09 14:16:36 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Encode SNMPv2c packet into bytes. + */ +ByteArrayOutputStream EncodeSNMPv2c(SnmpContextv2c context, byte msg_type, + int pduId, int errstat, int errind, Enumeration ve) + throws IOException, EncodingException +{ + ByteArrayOutputStream bout; + AsnSequence asnTopSeq; + + // Create authentication + asnTopSeq = new AsnSequence(); + asnTopSeq.add(new AsnInteger(SnmpConstants.SNMP_VERSION_2c)); + asnTopSeq.add(new AsnOctets(context.getCommunity())); // community + + // Create PDU sequence. + AsnObject asnPduObject = EncodePdu(msg_type, pduId, errstat, errind, ve); + asnTopSeq.add(asnPduObject); + + if (AsnObject.debug > 10) + { + System.out.println("\n" + getClass().getName() + ".EncodeSNMPv2c(): "); + } + // Write SNMP object + bout = new ByteArrayOutputStream(); + asnTopSeq.write(bout); + return bout; +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv3.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv3.java new file mode 100644 index 0000000..92ea33e --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnEncoderv3.java @@ -0,0 +1,313 @@ +// NAME +// $RCSfile: AsnEncoderv3.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2009/03/05 12:48:59 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; + +/** + * This class contains the v3 specific methods to encode a Pdu into bytes. + * We split the original class AsnEncoder into four classes. + * + * @since 4_14 + * @author Tim Panton + * @version $Revision: 3.5 $ $Date: 2009/03/05 12:48:59 $ + */ +class AsnEncoderv3 extends AsnEncoderBase +{ + private static final String version_id = + "@(#)$Id: AsnEncoderv3.java,v 3.5 2009/03/05 12:48:59 birgita Exp $ Copyright Westhawk Ltd"; + + // 12 zero octets + static byte dummyFingerPrint[] = + { + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + (byte)(0x0), + }; + +/** + * Encode SNMPv3 packet into bytes. + */ +byte[] EncodeSNMPv3(SnmpContextv3Basis context, + int contextMsgId, TimeWindowNode node, + byte msg_type, int pduId, int errstat, int errind, Enumeration ve) + throws IOException, EncodingException +{ + ByteArrayOutputStream bout; + // Create authentication + AsnSequence asnTopSeq = new AsnSequence(); + + // msgGlobalData = HeaderData + AsnSequence asnHeaderData = new AsnSequence(); + asnHeaderData.add(new AsnInteger(contextMsgId)); + asnHeaderData.add(new AsnInteger(context.getMaxRecvSize())); + asnHeaderData.add(new AsnOctets(getMsgFlags(context, msg_type))); + asnHeaderData.add(new AsnInteger(context.USM_Security_Model)); + + // msgData = ScopedPdu (plaintext or encrypted) + AsnSequence asnPlainScopedPdu = new AsnSequence(); + asnPlainScopedPdu.add(new AsnOctets(context.getContextEngineId())); + asnPlainScopedPdu.add(new AsnOctets(context.getContextName())); + // PDU sequence. + AsnObject asnPduObject = EncodePdu(msg_type, pduId, errstat, errind, ve); + asnPlainScopedPdu.add(asnPduObject); + + // asnSecurityParameters + if (AsnObject.debug > 10) + { + System.out.println("\nEncode USM: node " + node.toString()); + } + AsnSequence asnSecurityObject = new AsnSequence(); + byte [] engineIdBytes = SnmpUtilities.toBytes(node.getSnmpEngineId()); + asnSecurityObject.add(new AsnOctets(engineIdBytes)); + asnSecurityObject.add(new AsnInteger(node.getSnmpEngineBoots())); + asnSecurityObject.add(new AsnInteger(node.getSnmpEngineTime())); + asnSecurityObject.add(new AsnOctets(context.getUserName())); + + AsnOctets fingerPrintOct; + if (context.isUseAuthentication()) + { + fingerPrintOct = new AsnOctets(dummyFingerPrint); + } + else + { + fingerPrintOct = new AsnOctets(""); + } + asnSecurityObject.add(fingerPrintOct); + + AsnOctets privOct; + AsnOctets asnEncryptedScopedPdu = null; + if (context.isUsePrivacy()) + { + byte[] privKey = null; + int aprot = context.getAuthenticationProtocol(); + if (aprot == context.MD5_PROTOCOL) + { + byte[] passwKey = context.getPrivacyPasswordKeyMD5(); + privKey = SnmpUtilities.getLocalizedKeyMD5(passwKey, + node.getSnmpEngineId()); + } + else + { + byte[] passwKey = context.getPrivacyPasswordKeySHA1(); + privKey = SnmpUtilities.getLocalizedKeySHA1(passwKey, + node.getSnmpEngineId()); + } + + int pprot = context.getPrivacyProtocol(); + byte [] salt = null; + if (pprot == context.AES_ENCRYPT) + { + salt = SnmpUtilities.getSaltAES(); + } + else + { + salt = SnmpUtilities.getSaltDES(node.getSnmpEngineBoots()); + } + + privOct = new AsnOctets(salt); + bout = new ByteArrayOutputStream(); + asnPlainScopedPdu.write(bout); + + byte[] plaintext = bout.toByteArray(); + byte[] encryptedText = null; + if (pprot == context.AES_ENCRYPT) + { + encryptedText = SnmpUtilities.AESencrypt(plaintext, privKey, + node.getSnmpEngineBoots(), node.getSnmpEngineTime(), salt); + } + else + { + encryptedText = SnmpUtilities.DESencrypt(plaintext, privKey, salt); + } + + asnEncryptedScopedPdu = new AsnOctets(encryptedText); + if (AsnObject.debug > 10) + { + System.out.println("Encrypted body with "+context.ProtocolNames[pprot]); + } + } + else + { + privOct = new AsnOctets(""); + } + asnSecurityObject.add(privOct); + + ByteArrayOutputStream secOut = new ByteArrayOutputStream(); + asnSecurityObject.write(secOut); + byte [] bytes = secOut.toByteArray(); + AsnOctets asnSecurityParameters = new AsnOctets(bytes); + + + asnTopSeq.add(new AsnInteger(SnmpConstants.SNMP_VERSION_3)); + asnTopSeq.add(asnHeaderData); + asnTopSeq.add(asnSecurityParameters); + if (context.isUsePrivacy()) + { + asnTopSeq.add(asnEncryptedScopedPdu); + } + else + { + asnTopSeq.add(asnPlainScopedPdu); + } + + + if (AsnObject.debug > 10) + { + System.out.println("\n" + getClass().getName() + ".EncodeSNMPv3(): "); + } + // Write SNMP object + bout = new ByteArrayOutputStream(); + asnTopSeq.write(bout); + + int sz = bout.size(); + if (sz > context.getMaxRecvSize()) + { + throw new EncodingException("Packet size ("+ sz + + ") is > maximum size (" + context.getMaxRecvSize() +")"); + } + byte[] message = bout.toByteArray(); + + // can only do this at after building the whole message + if (context.isUseAuthentication()) + { + byte[] calcFingerPrint = null; + + int prot = context.getAuthenticationProtocol(); + if (prot == context.MD5_PROTOCOL) + { + byte[] passwKey = context.getAuthenticationPasswordKeyMD5(); + byte[] authkey = SnmpUtilities.getLocalizedKeyMD5(passwKey, + node.getSnmpEngineId()); + calcFingerPrint = SnmpUtilities.getFingerPrintMD5(authkey, + message); + } + else + { + byte[] passwKey = context.getAuthenticationPasswordKeySHA1(); + byte[] authkey = SnmpUtilities.getLocalizedKeySHA1(passwKey, + node.getSnmpEngineId()); + calcFingerPrint = SnmpUtilities.getFingerPrintSHA1(authkey, + message); + } + + int usmPos = asnSecurityParameters.getContentsPos(); + int fpPos = fingerPrintOct.getContentsPos(); + fpPos += usmPos; + if (AsnObject.debug > 10) + { + int fpLength = fingerPrintOct.getContentsLength(); + String str = "Pos finger print = " + fpPos + + ", len = " + fpLength; + SnmpUtilities.dumpBytes(str, calcFingerPrint); + } + + // Replace the dummy finger print with the real finger print + System.arraycopy(calcFingerPrint, 0, + message, fpPos, dummyFingerPrint.length); + } + return message; +} + + +private byte[] getMsgFlags(SnmpContextv3Basis context, byte msg_type) throws EncodingException +{ + byte authMask = (byte)(0x0); + if (context.isUseAuthentication()) + { + authMask = (byte)(0x1); + } + byte privMask = (byte)(0x0); + if (context.isUsePrivacy()) + { + if (context.isUseAuthentication()) + { + privMask = (byte)(0x2); + } + else + { + throw new EncodingException("Encryption without authentication is not allowed"); + } + } + byte reportMask = (byte)(0x0); + if (context.isAuthoritative(msg_type) == false) + { + reportMask = (byte)(0x4); + } + byte [] msgFlags = new byte[1]; + msgFlags[0] = (byte) (authMask | privMask | reportMask); + return msgFlags; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnInteger.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnInteger.java new file mode 100644 index 0000000..8cf7052 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnInteger.java @@ -0,0 +1,260 @@ +// NAME +// $RCSfile: AsnInteger.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2008/05/27 15:40:14 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +/** + * This class represents the ASN.1 32-bit signed integer + * + * @see SnmpConstants#ASN_INTEGER + * + * @author Tim Panton + * @version $Revision: 3.14 $ $Date: 2008/05/27 15:40:14 $ + */ +public class AsnInteger extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnInteger.java,v 3.14 2008/05/27 15:40:14 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * The internal value of AsnInteger. + */ + protected int value; + + /** + * Constructor. + * + * @param v The value of the AsnInteger + */ + public AsnInteger(int v) + { + value = v; + type = ASN_INTEGER; + } + + /** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnInteger + */ + public AsnInteger(InputStream in, int len) throws IOException + { + byte data[] = new byte[len]; + if (len != in.read(data,0,len)) + { + throw new IOException("AsnInteger(): Not enough data"); + } + int val = bytesToInteger(data); + value = val; + } + + /** + * Returns the value. + * + * @return The value of the AsnInteger + */ + public int getValue() + { + return value; + } + + /** + * Returns the string representation of the AsnInteger. + * + * @return The string of the AsnInteger + */ + public String toString() + { + return (String.valueOf(value)); + } + + /** + * Returns the number of bytes the integer occupies. + */ + int size() + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // 32-bit integer.. change to 56 to write 64-bit long + // loop through bytes in value while it is 'empty' + for(count=24; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + // Check sign bit.. make sure negative's MSB bit is 1, + // positives is 0 + // (0x00000080 = 0x00 0x80) 0xFFFFFF01 => 0xFF 0x01 + // (0x0000007F = 0x7F) 0xFFFFFF80 => 0x80 + if (((value >> count) & 0x80) != sign) count += 8; + return (count>>3)+1; + } + + + /** + * Output integer. + */ + void write(OutputStream out, int pos) throws IOException + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // Get count + for(count=24; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + if (((value >> count) & 0x80) != sign) count += 8; + + // Build header and write value + AsnBuildHeader(out, ASN_INTEGER, (count>>3)+1); + + if (debug > 10) + { + System.out.println("\tAsnInteger(): value = " + value + + ", pos = " + pos); + } + + for(; count>=0; count-=8) + { + out.write((byte)((value >> count) & 0xFF)); + } + } + + /** + * Changes an array of bytes into an int. + * Thanks to Julien Conan (jconan@protego.net) for improving + * this method. + * + * @param data the array of bytes + * @return the int representation of the array + */ + protected int bytesToInteger(byte[] data) throws IOException + { + DataInputStream dis = new DataInputStream( + new ByteArrayInputStream(data)); + + int val = 0; + int size = data.length; + + /* + * First byte contains the sign if the number is negative. Do this + * only for AsnInteger + */ + val = dis.readByte(); + + for (int n=1; ntrue if and only if the argument is not + * null and is an AsnInteger object that + * contains the same int value as this object. + * + * @param obj the object to compare with. + * @return true if the objects are the same; + * false otherwise. + */ + public boolean equals(Object obj) + { + if (obj instanceof AsnInteger) + { + return value == ((AsnInteger)obj).value; + } + return false; + } + + + /** + * Returns a hash code for this AsnInteger. + * + * @return a hash code value for this object, equal to the + * primitive int value represented by this + * AsnInteger object. + */ + public int hashCode() + { + return value; + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnNull.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnNull.java new file mode 100644 index 0000000..0efbf89 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnNull.java @@ -0,0 +1,149 @@ +// NAME +// $RCSfile: AsnNull.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2008/05/27 15:40:14 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +/** + * This class represents the ASN.1 Null object + * + * @author Tim Panton + * @version $Revision: 3.9 $ $Date: 2008/05/27 15:40:14 $ + */ +public class AsnNull extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnNull.java,v 3.9 2008/05/27 15:40:14 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * Default Constructor. + */ + public AsnNull() + { + type = ASN_NULL; + } + + /** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnInteger + */ + public AsnNull(InputStream in, int len) + { + this(); + } + + /** + * Returns the string representation of the AsnNull. + * + * @return The string of the AsnNull + */ + public String toString() + { + return "AsnNull"; + } + + void write(OutputStream out, int pos) throws IOException + { + AsnBuildHeader(out, ASN_NULL, 0); + } + +/** + * Compares this object to the specified object. + * The result is true if and only if the argument is not + * null and is a AsnNull object. + * + * @param anObject the object to compare this AsnNull + * against. + * @return true if the AsnNull are equal; + * false otherwise. + */ +public boolean equals(Object anObject) +{ + if (this == anObject) + { + return true; + } + if (anObject instanceof AsnNull) + { + AsnNull anotherNull = (AsnNull)anObject; + return true; + } + return false; +} + + +/** + * Returns a hash code for this object. + * @return a hash code value for this object. + */ +public int hashCode() +{ + int h = 5; + return h; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnObject.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnObject.java new file mode 100644 index 0000000..4546772 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnObject.java @@ -0,0 +1,605 @@ +// NAME +// $RCSfile: AsnObject.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.30 $ +// CREATED +// $Date: 2006/03/23 14:54:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; +import uk.co.westhawk.snmp.util.*; + +/** + * This class represents the ASN.1 base class. + * SMIv1 RFC1155-SMI. + * SMIv2 SNMPv2-SMI. + * + *
    + * <ASN Object> = <type> <length> <ASN Object>
    + * or
    + * <ASN Object> = <type> <length> <value>
    + * 
    + * + * @author Tim Panton + * @version $Revision: 3.30 $ $Date: 2006/03/23 14:54:09 $ + */ + +public abstract class AsnObject extends Object implements SnmpConstants +{ + private static final String version_id = + "@(#)$Id: AsnObject.java,v 3.30 2006/03/23 14:54:09 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * Indicates the level of debug printed. By default this is none + * (0). + * @see #setDebug(int) + */ + public static int debug = 0; + + /** + * The type of object. + */ + protected byte type; + + /** + * The starting position of the AsnObject in the SNMP sequence. That + * is the position of the 'type' byte. + */ + protected int startPos = 0; + + /** + * The length of the header. That is the number of bytes of the 'type' + * and 'length' fields. Since there are multiple valid encodings for + * a given AsnObject, this length is not fixed! + */ + protected int headerLength = 0; + + /** + * The length of the actual contents. That is the same as the value of + * the 'length' field. + */ + protected int contentsLength = 0; + + /** + * Flag to signal the object is of a correct type. + */ + protected boolean isCorrect = true; + + abstract void write (OutputStream out, int pos) + throws IOException, EncodingException; + + /** + * Returns a string representation of the object. + * @return The string + */ + public abstract String toString(); + +/** + * Sets the new, global level of debug information for the stack package. + * The default value is zero, i.e. no debug info at all. All debug + * messages are printed to System.out. + *

    + * The following messages will appear when debug is > (greater than): + *

    + *
      + *
    • 0 - IOExceptions that won't be thrown to the user
    • + *
    • 1 - DecodingExceptions that won't be thrown to the user (received message with wrong SNMP version)
    • + *
    • 2 - DecodingExceptions when trying to decode traps
    • + *
    • 3 - processIncomingResponse errors: (corresponding Pdu cannot be found)
    • + *
    • 4 - Discovery of EngineId, Timeline
    • + *
    • 5 - Receiving traps, version/host do not correspond
    • + *
    • 6 - Pdu messages, sending etc
    • + *
    • 10 - Asn decoding of incoming messages
    • + *
    • 12 - Transmitter messages, Socket messages
    • + *
    • 15 - Not so important IOExceptions, like InterruptedIOException
    • + *
    + * + * @param newDebug the new debug value + */ +public static void setDebug(int newDebug) +{ + debug = newDebug; +} + + AsnObject AsnReadHeader(InputStream in) throws IOException + { + return AsnReadHeader(in, 0); + } + + /** + * @param pos The starting position, i.e. the pos the 'type' byte. + */ + AsnObject AsnReadHeader(InputStream in, int pos) throws IOException + { + int len, got; + AsnObject ret = null; + int had = in.available(); + + //Type byte + type = (byte) in.read(); + if (type != -1) + { + len = getLengthPacket(in); + int off = in.available(); + int headLength = had - off; + + got = 0; + byte body[] = new byte[len]; + if (len > 0) + { + got = in.read(body, 0, len); + } + if (got > -1) + { + // Always decode, unless in.read returned an error + // (i.e. got == -1): + // + // 1. + // If we haven't received all bytes (i.e. got < len) + // we will still try and decode as much as we can: + // Since body[] has the length 'len' (i.e. the + // length according to the packet), it will be padded with + // zero + // + // 2. + // If len was 0, got would have been been -1, but since + // no read was performed, got is 0. + // A len of 0 is a valid case however. + + ByteArrayInputStream buf = new ByteArrayInputStream(body); + ret = AsnMakeMe(buf, type, len, pos, headLength); + + if (got != len) + { + ret.isCorrect = false; + if (debug > 10) + { + System.out.println("\nAsnObject.AsnReadHeader():" + + " incorrect packet. Length = " + (int) len + + ", Got = " + got); + } + } + } + else + { + if (debug > 10) + { + System.out.println("\nAsnObject.AsnReadHeader(): Length = " + + (int) len + + ", Got = " + got + + ". Not processing any further."); + } + } + } + return ret; + } + + + AsnObject AsnMakeMe(InputStream in, byte t, int len, int pos, + int headLength) throws IOException + { + AsnObject me = this; + type = t; + + switch (type) + { + case CONS_SEQ : + me = new AsnSequence(in, len, (pos+headLength)); + break; + case GET_REQ_MSG : + case GETNEXT_REQ_MSG : + case SET_REQ_MSG : + case GETBULK_REQ_MSG : + case INFORM_REQ_MSG : + case GET_RSP_MSG : + case GET_RPRT_MSG : + case TRPV2_REQ_MSG : + me = new AsnPduSequence(in, len, (pos+headLength)); + break; + case TRP_REQ_MSG : + me = new AsnTrapPduv1Sequence(in, len, (pos+headLength)); + break; + case ASN_INTEGER : + me = new AsnInteger(in, len); + break; + case TIMETICKS : + case COUNTER : + case GAUGE : + case OBSOLETED_RFC1442_UINTEGER32 : + me = new AsnUnsInteger(in, len); + break; + case COUNTER64 : + me = new AsnUnsInteger64(in, len); // TODO test + break; + case ASN_OBJECT_ID : + me = new AsnObjectId(in, len); + break; + case IPADDRESS : + case ASN_OCTET_STR : + case OPAQUE : + case NSAP_ADDRESS : + me = new AsnOctets(in, len); + break; + case ASN_NULL : + me = new AsnNull(in, len); + break; + case SNMP_VAR_NOSUCHOBJECT: + case SNMP_VAR_NOSUCHINSTANCE: + case SNMP_VAR_ENDOFMIBVIEW: + me = new AsnPrimitive(type); + break; + default : + if (debug > 0) + { + System.out.println("AsnObject.AsnMakeMe():" + + " Bad Type 0x" + SnmpUtilities.toHex(type)); + } + me = new AsnNull(in, len); + me.isCorrect = false; + break; + } + me.type = type; + me.startPos = pos; + me.headerLength = headLength; + me.contentsLength = len; + + if (debug > 10) + { + System.out.println("AsnObject.AsnMakeMe():" + + " headerLength = " + me.headerLength + + ", contentsLength = " + me.contentsLength); + System.out.println("\ttype = 0x" + + SnmpUtilities.toHex(type) + + ", " + me.getRespTypeString() + + ", " + me.getClass().getName() + + ": value = " + me.toString() + + ", startPos = " + me.startPos + + ", correct = " + me.isCorrect); + } + return me; + } + + /** Adds a child to the sequence + */ + AsnObject add (AsnObject child) + { + return child; + } + + /** recursively look for a pduSequence object + * if not overridden - then not a sequence - + */ + AsnObject findPdu() + { + return null; + } + + /** recursively look for a pduSequence object + * if not overridden - then not a sequence - + */ + AsnObject findTrapPduv1() + { + return null; + } + + /** + * Output ASN header. + */ + void AsnBuildHeader(OutputStream out, byte t, int length) + throws IOException + { + int count; + + type = t; + // Type byte + out.write(type); + + // Length bytes + count = getLengthBytes(length); + headerLength = count + 1; + contentsLength = length; + if (debug > 10) + { + System.out.println("AsnBuildHeader(): " + + "type = 0x" + SnmpUtilities.toHex(type) + + ", headerLength = " + headerLength + + ", contentsLength = " + contentsLength); + } + + if (count > 1) + { + // Write long form prefix byte + --count; + byte tmp = (byte) (0x80 | (byte) count); + out.write(tmp); + } + while(count!=0) + { + // Write length bytes + out.write((byte)((length >> (--count << 3)) & 0xFF)); + } + } + + int size() throws EncodingException + { + return 0; + } + + /** + * Returns length field size for a packet length. + * Returns: + * 1 if length will fit in short form (0x00-0x7f) + * 2+ if length >= 0x80 + */ + int getLengthBytes(int length) + { + int mask, count; + + if (length < 0x80) + { + // Short form.. 1 byte + return 1; + } + else + { + // Long form.. prefix byte + length bytes + mask = 0xFF000000; + for(count=4; (length&mask)==0; count--) + { + mask >>= 8; + } + return count+1; + } + } + + + int getLengthPacket(InputStream in) throws IOException + { + int length = 0; + byte mask =(byte) 0x7f; + byte len = (byte) in.read(); + + if ((0x80 & len) != 0) + { + // long form + + int count = (mask & len); + if (count < 4) + { + byte data[] = new byte[count]; + int n = in.read(data, 0, count); + if (n != count) + { + throw new IOException("AsnObject.getLengthPacket(): Not enough data"); + } + else + { + /* + * Thanks to Julien Conan (jconan@protego.net) + * for improving this code. + */ + DataInputStream dis = new DataInputStream( + new ByteArrayInputStream(data)); + + for (n=0; nTim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +// unsigned 32-bit integers encoded in the following format: +// MSB..LSB +// 76543210 +// xyyyyyyy +// .\ / +// . \ / +// . \ / +// . +-------- OID bits +// +------------ 0 if this is the last byte, 1 if additional bytes follow +// +// Output sid in the form: abcdefgh.ijklmnop.qrstuvwx.yzABCDEF +// +// if (abcd != 0) { +// output 1.000abcd 1.efghijk 1.lmnopqr 1.stuvwxy 0.zABCDEF +// } else if (efghijk != 0) { +// output 1.efghijk 1.lmnopqr 1.stuvwxy 0.zABCDEF +// } else if (lmnopqr != 0) { +// output 1.lmnopqr 1.stuvwxy 0.zABCDEF +// } else if (stuvwxy != 0) { +// output 1.stuvwxy 0.zABCDEF +// } else { +// output 0.zABCDEF +// } + + +/** + * This class represents the ASN.1 ObjectID class. An Object ID (OID) + * identifies a variable in a MIB. + * + * @author Tim Panton + * @version $Revision: 3.25 $ $Date: 2008/08/19 13:34:13 $ + */ +public class AsnObjectId extends AsnObject implements Comparable +{ + private static final String version_id = + "@(#)$Id: AsnObjectId.java,v 3.25 2008/08/19 13:34:13 birgita Exp $ Copyright Westhawk Ltd"; + + // Thanks to Ken Swanson (gks@navcomm1.dnrc.bell-labs.com) for + // pointing out that this should be an array of longs. + + // default value for test purposes. + // private long value[] = {1,3,6,1,4,1,674,10889,2,1,0}; + private long value[] = {}; + + /** + * Thanks to Robert Kostes . + * @see #toString(long[]) + */ + final static char[] digits = {'0','1','2','3','4','5','6','7','8','9'}; + +/** + * The empty constructor. + */ +protected AsnObjectId() +{ + type = ASN_OBJECT_ID; +} + +/** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnInteger + */ +AsnObjectId(InputStream in, int len) throws IOException +{ + // get our data + byte data[] = new byte[len]; + if (len != in.read(data,0,len)) + { + throw new IOException("AsnObjectId(): Not enough data"); + } + + // now decide how many SID we will need + // count the bytes with 0 in the top bit - then add 1 + int sids = 1; // first byte has 2 sids in it + for (int off=0; off= 0) + { + sids++; + } + } + // so allocate some space for the sids + value = new long[sids]; + + // decode the first two + if (len > 0) + { + value[0] = data[0] / 40; + if (value.length > 1) + { + value[1] = data[0] % 40; + } + } + + // now decode the rest + int off = 1; + for (int idx=2; idx 0) + { + StringTokenizer tok = new StringTokenizer(s, "."); + int count = tok.countTokens(); + oidArray = new long[count]; + + int n=0; + while (tok.hasMoreTokens()) + { + try + { + String num = tok.nextToken(); + Long val = Long.valueOf(num); + oidArray[n] = val.longValue(); + n++; + } + catch (NumberFormatException exc) + { + throw new IllegalArgumentException("AsnObjectId(): Bad OID '" + + s + "' " + exc.getMessage()); + } + catch (NoSuchElementException exc) + { + } + } + } + else + { + throw new IllegalArgumentException("AsnObjectId(): Bad OID '" + + s + "' "); + } + + return oidArray; +} + + +/** + * Checks if this OID starts with the specified prefix. + * + * @return true if starts with the prefix, false otherwise + */ +public boolean startsWith(AsnObjectId prefix) +{ + boolean sw = true; + if (prefix.value.length < this.value.length) + { + int pos=0; + while (pos < prefix.value.length && sw == true) + { + sw = (prefix.value[pos] == this.value[pos]); + pos++; + } + } + else + { + sw = false; + } + return sw; +} + +/** + * Adds a single sub-identifier to the end of the OID. + * + * @param sub_oid The sub-identifier + */ +public void add(long sub_oid) +{ + int size = value.length; + + long tmp_value[] = value; + value = new long[size+1]; + System.arraycopy(tmp_value, 0, value, 0, size); + value[size] = sub_oid; +} + + +/** + * Adds a number of sub-identifiers to the end of the OID. + * + * @param sub_oid The sub-identifiers + * @see AsnOctets#toSubOid + */ +public void add(long[] sub_oid) +{ + int size1 = value.length; + int size2 = sub_oid.length; + + long tmp_value[] = value; + value = new long[size1+size2]; + System.arraycopy(tmp_value, 0, value, 0, size1); + System.arraycopy(sub_oid, 0, value, size1, size2); +} + + +/** + * Adds sub-identifiers to the end of the OID. + * + * @param s The sub-identifiers, format a[.b]* + */ +public void add(String s) throws IllegalArgumentException +{ + long [] sub_oid = toArrayOfLongs(s); + add(sub_oid); +} + +/** + * Removes the last sub-identifier (if available) from this + * OID and returns it. + * @return The sub-identifier or -1 if there is no sub-identifier + * @since 6.1 + */ +public long removeLast() +{ + long lastSubOid = -1; + int size = value.length; + if (size > 0) + { + // get the last sub-oid + size -= 1; + lastSubOid = value[size]; + + // remove the last sub-oid + long tmp_value[] = value; + value = new long[size]; + System.arraycopy(tmp_value, 0, value, 0, size); + } + return lastSubOid; +} + + +/** + * Returns the total size of the object ID. + */ +int size() throws EncodingException +{ + int val, idx, len; + + if (value.length > 1) + { + // First entry = OID[0]*40 + OID[1]; + len = getSIDLen(value[0]*40 + value[1]); + for(idx=2; idx 10) + { + System.out.println("\tAsnObjectId(): value = " + this.toString() + + ", pos = " + pos); + } + + // Output data bytes + if (value.length > 1) + { + // First entry = OID[0]*40 + OID[1]; + EncodeSID(out, value[0]*40 + value[1]); + for(idx=2; idx>=7) != 0; count++) + ; + return count; +} + +/** + * Encode OID subidentifier. + */ +private void EncodeSID(OutputStream out, long value) throws IOException +{ + byte mask = (byte)0x0F; + int count = 0; + + // Upper mask is 4 bits + mask = 0xF; + + // Loop while value and mask is zero + for(count=28; count>0; count-=7) + { + if (((value >> count) & mask) != 0) break; + mask = 0x7f; + } + + // While count, output value. If this isn't the last byte, output + // 0x80 | value. + for(; count>=0; count-=7) + { + out.write((byte)(((value >> count) & mask) | (count>0 ? 0x80 : 0x00)) ); + mask = 0x7f; + } +} + + +/** + * Returns the value of the AsnObjectId. + * + * @return The value (the OID) + */ +public String getValue() +{ + return toString(); +} + + +/** + * Returns the string representation of the AsnObjectId. + * + * @return The string of the AsnObjectId + */ +public String toString() +{ + return toString(value); +} + +/** + * Returns the string representation of the AsnObjectId. + * + * @return The string of the AsnObjectId + */ +public String toString(long v[]) +{ + StringBuffer buffer = new StringBuffer(""); + if (v.length > 0) + { + for (int n=0; n < v.length-1 && n<100 ; n++) + { + // optimization, thanks to Robert Kostes who + // did some profiling. + if (0 <= v[n] && v[n] <= 9) + { + // append a fixed char + int i = (int) v[n]; + buffer.append(digits[i]); + } + else + { + // go through number conversion + buffer.append(v[n]); + } + buffer.append("."); + } + if (v.length-1 > 100) + { + buffer.append("[.. cut ..]."); + } + buffer.append(v[v.length-1]); + } + return buffer.toString(); +} + +/** + * Returns the number of elements in the AsnObjectId. + * We cannot use size(), since that is already in use. + * + * @return the number of elements + */ +public int getSize() +{ + return value.length; +} + +/** + * Returns the element in the AsnObjectId at the specified index. + * + * @param index The index + * @return the element at the specified index + * @exception ArrayIndexOutOfBoundsException if an invalid + * index was given + */ +public synchronized long getElementAt(int index) + throws ArrayIndexOutOfBoundsException +{ + if (index >= value.length) + { + throw new ArrayIndexOutOfBoundsException(index + + " >= " + value.length); + } + try + { + return value[index]; + } + catch (ArrayIndexOutOfBoundsException exc) + { + throw new ArrayIndexOutOfBoundsException(index + " < 0"); + } +} + +/** + * Returns the last element in the AsnObjectId. + * + * @return the last element + * @exception ArrayIndexOutOfBoundsException if the + * AsnObjectId is empty. + * @since 6.1 + */ +public long lastElement() + throws ArrayIndexOutOfBoundsException +{ + return getElementAt(value.length-1); +} + +/** + * Returns the value of the AsnObjectId as an array of long. The value + * returned is a copy. + * + * @return The OID value + * @since 4_14 + */ +public long[] getOid() +{ + int len = value.length; + long [] oida = new long[len]; + System.arraycopy(value, 0, oida, 0, len); + return oida; +} + + +/** + * Returns a subset of the value of the AsnObjectId as an array of long. + * The value returned is a copy. + * + * @return The sub OID value + * @since 4_14 + */ +public long[] getSubOid(int beginIndex, int endIndex) +throws ArrayIndexOutOfBoundsException +{ + int len1 = value.length; + if (beginIndex < 0) + { + throw new ArrayIndexOutOfBoundsException(beginIndex + " < 0"); + } + if (endIndex > len1) + { + throw new ArrayIndexOutOfBoundsException(endIndex + " > " + len1); + } + if (beginIndex > endIndex) + { + throw new ArrayIndexOutOfBoundsException(beginIndex + " > " + endIndex); + } + + int len2 = endIndex - beginIndex; + long [] oida = new long[len2]; + System.arraycopy(value, beginIndex, oida, 0, len2); + return oida; +} + + + +/** + * Compares this OID to the specified object. + * The result is true if and only if the argument is not + * null and is a AsnObjectId object that represents + * the same sequence of numbers as this object. + * + * + *

    + * Thanks to Eli Bishop (eli@graphesthesia.com) for the suggestion of + * adding it. + *

    + * + * @param anObject The object to compare this AsnObjectId + * against. + * @return true if the AsnObjectId are equal; + * false otherwise. + */ +public boolean equals(Object anObject) +{ + if (this == anObject) + { + return true; + } + if (anObject instanceof AsnObjectId) + { + AsnObjectId anotherOid = (AsnObjectId)anObject; + int n = value.length; + if (n == anotherOid.value.length) + { + long v1[] = value; + long v2[] = anotherOid.value; + int i = 0; + int j = 0; + while (n-- != 0) + { + if (v1[i++] != v2[j++]) + { + return false; + } + } + return true; + } + } + return false; +} + + +/** + * Returns a hash code for this OID. + * The hash value of the empty OID is zero. + * + * @return a hash code value for this object. + */ +public int hashCode() +{ + int h = 0; + if (h == 0) + { + int off = 0; + long val[] = value; + int len = value.length; + + for (int i=0; i>> 32)); + h = 31*h + hi; + } + } + return h; +} + + +/** + * @see Comparable#compareTo + * @see #compareTo(AsnObjectId) + * @since 6.1 + */ +public int compareTo(Object o) +{ + return compareTo((AsnObjectId) o); +} + +/** + * @see Comparable#compareTo + * Thanks to Josh Bers to providing this code. + * @since 6.1 + */ +public int compareTo(AsnObjectId b) +{ + if (b == null) + { + throw new NullPointerException("Trying to compare with null"); + } + + int aElts = getSize(); + int bElts = b.getSize(); + + if ((aElts == 0) && (bElts > 0)) + { + return -1; + } + if ((bElts == 0) && (aElts > 0)) + { + return 1; + } + + for (int i=0; (i < aElts) && (i < bElts); i++) + { + if (getElementAt(i) != b.getElementAt(i)) + { + if (getElementAt(i) > b.getElementAt(i)) + { + return 1; + } + else + { + return -1; + } + } + } + + // equal to the end of one object + if (aElts > bElts) + { + return 1; + } + else if (bElts > aElts) + { + return -1; + } + + // both objects same + return 0; +} + + +/** + * Compares the n leftmost sub-identifiers with the given + * AsnObject in left-to-right direction. + * @param n The number of sub-identifiers to compare. + * @param b An AsnObject to compare with this object + * @return + *
      + *
    • + * 0, when the first 'n' sub-identifiers are the same. + *
    • + *
    • + * -1 when the first 'n' sub-identifiers of this object are + * lexicographic less than those of b. This includes the case where + * this object is shorter than 'n' AND shorter than b. + *
    • + *
    • + * 1 when the first 'n' sub-identifiers of this object are + * lexicographic greater than those of b. + *
    • + *
    + * @since 6.1 + */ +public int leftMostCompare(int n, AsnObjectId b) +{ + if (b == null) + { + throw new NullPointerException("Trying to compare with null"); + } + + int aElts = getSize(); + int bElts = b.getSize(); + + + int min = Math.min(aElts, bElts); + if (min < n) + { + if (aElts > bElts) + { + return 1; + } + else if (bElts > aElts) + { + return -1; + } + else + { + return this.compareTo(b); + } + } + else + { + // min >= n + long[] aOids = getSubOid(0, n); + long[] bOids = b.getSubOid(0, n); + AsnObjectId aCopy = new AsnObjectId(aOids); + AsnObjectId bCopy = new AsnObjectId(bOids); + return aCopy.compareTo(bCopy); + } +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnOctets.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnOctets.java new file mode 100644 index 0000000..4f785f7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnOctets.java @@ -0,0 +1,989 @@ +// NAME +// $RCSfile: AsnOctets.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.39 $ +// CREATED +// $Date: 2006/03/23 14:54:10 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.util.*; +import java.io.*; +import java.util.*; +import java.net.InetAddress; +import java.text.SimpleDateFormat; + +/** + * This class represents the ASN.1 Octet class. + * It can be used for Octets, Ip Addresses and Opaque primitive types. + * + * The Octets type (ASN_OCTET_STR) is used for some text convensions. + * This class supports the DateAndTime, DisplayString and + * InternationalDisplayString and Ipv6Address text convensions. + *
    + * Note, the SNMP representation of IPv4 and IPv6 is different: + *
      + *
    • IPv4: IPADDRESS (or ASN_OCTET_STR, see rfc 4001)
    • + *
    • IPv6: ASN_OCTET_STR
    • + *
    + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @see SnmpConstants#ASN_OCTET_STR + * @see SnmpConstants#IPADDRESS + * @see SnmpConstants#OPAQUE + * + * @author Tim Panton + * @version $Revision: 3.39 $ $Date: 2006/03/23 14:54:10 $ + */ +public class AsnOctets extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnOctets.java,v 3.39 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The hexadecimal prefix that is used when printing a hexadecimal + * number in toString(). By default this is "0x". + */ + public static String HEX_PREFIX = "0x"; + + /** + * The object that is used in toCalendar() to format the calendar + * representation of the Octets according to the DateAndTime text + * convension. + * The pattern is "yyyy-M-d,HH:mm:ss.SS,z". + * + * @see #getCalendar() + * @see #toCalendar() + * @see SimpleDateFormat + */ + public static SimpleDateFormat CALFORMAT = new SimpleDateFormat("yyyy-M-d,HH:mm:ss.SS,z"); + + /** + * The default AsnOctetsPrintableFace object. + * + * @see #setPrintable + * @see DefaultAsnOctetsPrintable + */ + public static AsnOctetsPrintableFace printableObject = new DefaultAsnOctetsPrintable(); + + byte value[]; + + /** Cache the hash code for the OID */ + private int hash = 0; + + /** + * Constructor. The type of the AsnOctets defaults to ASN_OCTET_STR. + * + * @param s The byte array representing the AsnOctets + * @see SnmpConstants#ASN_OCTET_STR + */ + public AsnOctets(byte s[]) + throws IllegalArgumentException + { + this(s, ASN_OCTET_STR); + } + + /** + * Constructor to create a specific type of AsnOctets. + * + * @param s The byte array representing the AsnOctets + * @param t The type of the AsnOctets + * @see SnmpConstants#ASN_OCTET_STR + * @see SnmpConstants#IPADDRESS + * @see SnmpConstants#OPAQUE + */ + public AsnOctets(byte s[], byte t) + throws IllegalArgumentException + { + value = s; + type = t; + if (value == null) + { + throw new IllegalArgumentException("Value is null"); + } + } + + /** + * Constructor. The type of the AsnOctets defaults to ASN_OCTET_STR. + * + * @param s The character array representing the AsnOctets + * @see SnmpConstants#ASN_OCTET_STR + */ + public AsnOctets(char s[]) + { + int idx; + + value = new byte[s.length]; + type = ASN_OCTET_STR; + for (idx=0; idx + * Note, the SNMP representation of IPv4 and IPv6 is different: + *
      + *
    • IPv4: IPADDRESS (or ASN_OCTET_STR, see rfc 4001)
    • + *
    • IPv6: ASN_OCTET_STR
    • + *
    + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @param iad The Inet Address + * + * @see #AsnOctets(Inet4Address, byte) + */ + public AsnOctets(InetAddress iad) + throws IllegalArgumentException + { + this(iad.getAddress(), ASN_OCTET_STR); + if (iad instanceof java.net.Inet4Address) + { + // IPv4 + type = IPADDRESS; + } + else + { + // IPv6 is ASN_OCTET_STR, so do nothing + } + } + + + /** + * Constructor to create an ASN IPv4 Address. + * If the address is an IPv4 address, it can either be represented + * by IPADDRESS or as ASN_OCTET_STR. + * + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @param iad The IPv4 Inet Address + * @param t The type of the AsnOctets + * + * @see #AsnOctets(InetAddress) + * @see SnmpConstants#IPADDRESS + * @see SnmpConstants#ASN_OCTET_STR + * @since 4_14 + */ + public AsnOctets(java.net.Inet4Address iad, byte t) + throws IllegalArgumentException + { + this(iad.getAddress(), t); + } + + + /** + * Constructor for DateAndTime text convension. + * See + * SNMPv2-TC + * + *
    +     *      field  octets  contents                  range
    +     *      -----  ------  --------                  -----
    +     *        1      1-2   year*                     0..65536
    +     *        2       3    month                     1..12
    +     *        3       4    day                       1..31
    +     *        4       5    hour                      0..23
    +     *        5       6    minutes                   0..59
    +     *        6       7    seconds                   0..60
    +     *                     (use 60 for leap-second)
    +     *        7       8    deci-seconds              0..9
    +     *
    +     *        8       9    direction from UTC        '+' / '-'
    +     *        9      10    hours from UTC*           0..13
    +     *       10      11    minutes from UTC          0..59
    +     *
    +     * SYNTAX       OCTET STRING (SIZE (8 | 11))
    +     * 
    + * + * @since 4_14 + */ + public AsnOctets(Calendar cal) + { + value = new byte[11]; + type = ASN_OCTET_STR; + + int year = cal.get(Calendar.YEAR); + // Calendar: 0=January + int month = cal.get(Calendar.MONTH)+1; + int day = cal.get(Calendar.DAY_OF_MONTH); + int hour = cal.get(Calendar.HOUR_OF_DAY); + int min = cal.get(Calendar.MINUTE); + int sec = cal.get(Calendar.SECOND); + int msec = cal.get(Calendar.MILLISECOND); + int msecGMT = cal.get(Calendar.ZONE_OFFSET); + + // The value of year is in network-byte order + // Is this correct? + value[0] = (byte) ((year / 256) % 256); + value[1] = (byte) (year % 256); + + value[2] = (byte) (month & 0xFF); + value[3] = (byte) (day & 0xFF); + value[4] = (byte) (hour & 0xFF); + value[5] = (byte) (min & 0xFF); + value[6] = (byte) (sec & 0xFF); + value[7] = (byte) ((msec / 100) & 0xFF); + + char dir = '\0'; + if (msecGMT < 0) + { + dir = '-'; + msecGMT = msecGMT * -1; + } + else + { + dir = '+'; + } + value[8] = (byte) dir; + + if (msecGMT == 0) + { + value[9] = 0x00; + value[10] = 0x00; + } + else + { + int minGMT = (int) (((double) msecGMT) / 1000.0 / 60.0); + if (minGMT == 0) + { + value[9] = 0x00; + value[10] = 0x00; + } + else + { + int hourGMT = (int) (minGMT / 60.0); + minGMT = minGMT - (hourGMT * 60); + value[9] = (byte) (hourGMT & 0xFF); + value[10] = (byte) (minGMT & 0xFF); + } + } + } + + /** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnOctets + */ + public AsnOctets(InputStream in, int len) throws IOException + { + value = new byte[len]; + if (len != 0) + { + if (len == in.read(value,0,len)) + { + String str = ""; + //str = new String(value); + } + else + { + throw new IOException("AsnOctets(): Not enough data"); + } + } + else + { + // if len is zero, the in.read will return -1 + // a length of zero is a valid case. + ; + } + } + + /** + * Sets the global hexadecimal prefix. This prefix will be used in + * toString() when it prints out a hexadecimal number. It is not + * used in toHex(). The default is "0x". + * + * @see #toString() + * @see #toHex() + * @see #HEX_PREFIX + */ + public static void setHexPrefix(String newPrefix) + { + HEX_PREFIX = newPrefix; + } + + /** + * Sets the global AsnOctetsPrintableFace printableObject. This + * object will be used in the toString() and the + * toInternationalDisplayString() methods. + * + * @see #toString + * @see #toInternationalDisplayString + * @since 4_14 + */ + public static void setPrintable(AsnOctetsPrintableFace obj) + { + if (obj != null) + { + printableObject = obj; + } + } + + + /** + * Returns the String value. Calls toString(). + * + * @return The value of the AsnOctets + * @see #toString() + */ + public String getValue() + { + return toString(); + } + + /** + * Returns the bytes. This returns a copy of the internal byte array. + * + * @return The bytes of the AsnOctets + */ + public byte[] getBytes() + { + int len = value.length; + byte [] bytea = new byte[len]; + System.arraycopy(value, 0, bytea, 0, len); + return bytea; + } + + /** + * Returns the string representation of the AsnOctets. + *

    + * The string will have one of the following formats: + *

    + *
      + *
    • if this class represents an IP Address (v4), it will call + * toIpAddress()
    • + *
    • <prefix>aa[:bb]*, if this class represents a non-printable + * string or has type OPAQUE. + * The output will be in hexadecimal numbers (see toHex()). It will be prefixed + * according to the hex. prefix value
    • + *
    • a printable string, if this class seems printable
    • + *
    + * + *

    + * When the type is ASN_OCTET_STR, this method uses the + * AsnOctetsPrintableFace.isPrintable() to determine whether or not + * the string is printable. If it is printable, it will use + * AsnOctetsPrintableFace.toInternationalDisplayString() to + * transform the Octets to a String. + *

    + * + *
    + * Note, the SNMP representation of IPv4 and IPv6 is different: + *
      + *
    • IPv4: IPADDRESS (or ASN_OCTET_STR, see rfc 4001)
    • + *
    • IPv6: ASN_OCTET_STR
    • + *
    + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @see #HEX_PREFIX + * @see #setHexPrefix(String) + * @see #toHex + * @see #toIpAddress + * @see AsnOctetsPrintableFace#isPrintable + * @see AsnOctetsPrintableFace#toInternationalDisplayString + * @return The string representation of the AsnOctets + */ + public String toString() + { + return toString(printableObject); + } + + /** + * As toString(), but this methods will use this specific, one-off + * AsnOctetsPrintableFace object. + * + * @see #toString() + * @since 4_14 + */ + public String toString(AsnOctetsPrintableFace face) + { + String str = ""; + + if (type == IPADDRESS) + { + // for IPv4 only + str = toIpAddress(); + } + else if (type == OPAQUE) + { + str = HEX_PREFIX + toHex(); + } + else + { + boolean isPrintable = face.isPrintable(value); + if (isPrintable) + { + str = face.toInternationalDisplayString(value); + } + else + { + str = HEX_PREFIX + toHex(); + } + } + return str; + } + + + int size() + { + return value.length; + } + + void write(OutputStream out, int pos) throws IOException + { + int idx; + + // Output header + AsnBuildHeader(out, type, value.length); + if (debug > 10) + { + System.out.println("\tAsnOctets(): value = " + toString() + + ", pos = " + pos); + } + + // Output data + for (idx=0; idx + *
  • IPv4: IPADDRESS (or ASN_OCTET_STR, see rfc 4001)
  • + *
  • IPv6: ASN_OCTET_STR
  • + * + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @return The IP Address representation. + * @see #toString + * @see #getIpAddress + * @see SnmpConstants#ASN_OCTET_STR + * @see SnmpConstants#IPADDRESS + */ + /* + TODO: use Java's java.net.InetAddress, so it can be used for IPv4, and IPv6. + */ + public String toIpAddress() + { + /* TODO: Does this work? Yes, but will not compile in jdk 1.2.X, and + * in order to load (a part of) the stack in Oracle, I need + * 1.2.X + */ + /* + String str = ""; + try + { + InetAddress iad = InetAddress.getByAddress(value); + str = iad.getHostAddress(); + } + catch (java.net.UnknownHostException exc) { } + */ + + /* + */ + StringBuffer sb = new StringBuffer(39); + int length; + long val; + length = value.length; + if (length > 0) + { + if (length > 4) + { + // IPv6 + // Nicked this code from Inet6Address.numericToTextFormat + for (int i=0; i + *
  • IPv4: IPADDRESS (or ASN_OCTET_STR, see rfc 4001)
  • + *
  • IPv6: ASN_OCTET_STR
  • + * + * See also + * IPV6-TC, + * SNMPv2-PDU, + * INET-ADDRESS-MIB. + * + * @return The IP Address representation. + * @exception RuntimeException Thrown when the Octets does + * not represent an InetAddress or when the method internally throws + * an java.net.UnknownHostException + * + * @see #toString + * @see #toIpAddress + * @see SnmpConstants#ASN_OCTET_STR + * @see SnmpConstants#IPADDRESS + * @since 4_14 + */ + public InetAddress getIpAddress() + throws RuntimeException + { + InetAddress iad = null; + try + { + iad = InetAddress.getByAddress(value); + } + catch (java.net.UnknownHostException exc) + { + throw new RuntimeException(exc); + } + return iad; + } + + /** + * Returns the positive long for an octet. Only if type is IPADDRESS + * can the value be negative anyway. + */ + private long getPositiveValue(int index) + { + long val = (long) value[index]; + if (val <0) + { + val += 256; + } + return val; + } + + /** + * Returns this Octet as an hexadecimal String, without any prefix. + * + * @return The hex representation. + * @see #toString + */ + public String toHex() + { + int length; + StringBuffer buffer = new StringBuffer(""); + + length = value.length; + if (length > 0) + { + for (int i=0; i + * DisplayString + * represents textual information taken from the NVT + * ASCII character set, as defined in pages 4, 10-11 + * of RFC 854. + * Any object defined using this syntax + * may not exceed 255 characters in length. + * Basicly it is US-ASCII with some changes. + *

    + * + * @return The string representation. + * @see #toString + */ + public String toDisplayString() + { + String str = ""; + int length; + + length = value.length; + if (length > 0) + { + try + { + str = new String(value, "US-ASCII"); + } + catch (UnsupportedEncodingException exc) + { + str = new String(value); + } + str = str.trim(); + } + + return str; + } + + /** + * Returns this Octet as an international display string (text + * convension). + * It calls AsnOctetsPrintableFace.toInternationalDisplayString(). + * + * See + * HOST-RESOURCES-MIB + * + * @see AsnOctetsPrintableFace#toInternationalDisplayString + * @since 4_14 + */ + public String toInternationalDisplayString() + { + return toInternationalDisplayString(printableObject); + } + + + /** + * As toInternationalDisplayString(), but this methods will use this + * specific, one-off AsnOctetsPrintableFace object. + * + * @see #toInternationalDisplayString + * @since 4_14 + */ + public String toInternationalDisplayString(AsnOctetsPrintableFace face) + { + return face.toInternationalDisplayString(value); + } + + + /** + * Returns the String representation according to the DateAndTime + * convension. + * This string it returns is not exactly the same as the + * DISPLAY-HINT indicates. + * See + * SNMPv2-TC + * + * @since 4_14 + * @exception RuntimeException Thrown when the number of + * Octets does not represent the DateAndTime length. + * @see #CALFORMAT + */ + public String toCalendar() + throws RuntimeException + { + Calendar cal = this.getCalendar(); + Date date = cal.getTime(); + return CALFORMAT.format(date); + } + + /** + * Returns the Octets as Calendar according to the DateAndTime text + * convension. You can only call this method if + * the syntax of this Octet is the DateAndTime text convension. + * + * @exception RuntimeException Thrown when the number of + * Octets does not represent the DateAndTime length. + * + * @since 4_14 + * @see #AsnOctets(Calendar) + */ + public Calendar getCalendar() + throws RuntimeException + { + Calendar cal = Calendar.getInstance(); + if (value.length == 8 || value.length == 11) + { + int year = (int) ((getPositiveValue(0) * 256) + getPositiveValue(1)); + // Calendar: 0=January + int month = value[2]-1; + int day = value[3]; + int hour = value[4]; + int min = value[5]; + int sec = value[6]; + int msec = value[7] * 100; + cal.set(year, month, day, hour, min, sec); + cal.set(Calendar.MILLISECOND, msec); + + if (value.length == 11) + { + char dir = (char) value[8]; + int hourUTC = value[9]; + int minUTC = value[10]; + int secUTC = (hourUTC * 60) * 60; + + int msecGMT = secUTC * 1000; + if (dir == '-') + { + msecGMT = msecGMT * -1; + } + + cal.set(Calendar.ZONE_OFFSET, msecGMT); + } + } + else + { + throw new RuntimeException("AsnOctets is not DateAndTime"); + } + return cal; + } + + +/** + * Converts this Octet to its corresponding sub-identifiers. + * Each octet will be encoded in a separate sub-identifier, by + * converting the octet into a positive long. + * + *

    + * Use this method when building an OID when this Octet specifies a + * conceptual row. For example ipNetToMediaEntry, see + * IP-MIB + * or SnmpCommunityEntry, see + * SNMP-COMMUNITY-MIB + *

    + * + *

    + * The variable length_implied indicates that this MIB variable + * is preceded by the IMPLIED keyword: + *

    + *
      + *
    • + * The IMPLIED keyword can only be present for an Octet having + * a variable-length syntax (e.g., variable-length strings or object + * identifier-valued objects). + *
    • + *
    • + * The IMPLIED keyword can only be associated with the last + * object in the INDEX clause. + *
    • + *
    • + * The IMPLIED keyword may not be used on a variable-length + * string Octet if that string might have a value of zero-length. + *
    • + *
    + * + *

    + * If the length is implied, no extra sub-identifier will be created to + * indicate its length.
    + * If the length is not implied, the first + * sub-identifier will be the length of the Octet. + *

    + * + *

    + * If this Octet is of type IPADDRESS, length_implied should be false. + *

    + * + *

    + * The mapping of the INDEX clause is + * explained in SNMPv2-SMI, + * section 7.7. + *

    + * + * @param length_implied Indicates if the length of this octet is + * implied. + * + * @see AsnObjectId#add(long[]) + */ +public long [] toSubOid(boolean length_implied) +{ + long sub_oid[]; + int index = 0; + int length = value.length; + + if (length_implied) + { + sub_oid = new long[length]; + } + else + { + sub_oid = new long[length+1]; + sub_oid[0] = length; + index++; + } + + for (int i=0; itrue if and only if the argument is not + * null and is an AsnOctets object that represents + * the same sequence of octets as this Octet. + * + * @param anObject the object to compare this AsnOctets + * against. + * @return true if the AsnOctets are equal; + * false otherwise. + */ +public boolean equals(Object anObject) +{ + if (this == anObject) + { + return true; + } + if (anObject instanceof AsnOctets) + { + AsnOctets anotherOctet = (AsnOctets)anObject; + int n = value.length; + if (n == anotherOctet.value.length) + { + byte v1[] = value; + byte v2[] = anotherOctet.value; + int i = 0; + int j = 0; + while (n-- != 0) + { + if (v1[i++] != v2[j++]) + { + return false; + } + } + return true; + } + } + return false; +} + + +/** + * Returns a hash code for this Octet. The hash code for a + * AsnOctets object is computed as + *
    + * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    + * 
    + * using int arithmetic, where s[i] is the + * ith character of the Octet, n is the length of + * the Octet, and ^ indicates exponentiation. + * (The hash value of the empty Octet is zero.) + * + * @return a hash code value for this Octet. + */ +public int hashCode() +{ + int h = hash; + if (h == 0) + { + int off = 0; + byte val[] = value; + int len = value.length; + + for (int i=0; iwww.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This interface contains the isPrintable() method that is used to decided + * whether or not an AsnOctets with type ASN_OCTET_STR is printable or not. + * This interface has no effect on the way AsnOctets with type IPADDRESS + * or OPAQUE are printed. + * + *

    + * When the type is ASN_OCTET_STR, the method tries to guess whether + * or not the string is printable; without the knowledge of the MIB + * it cannot distinguish between OctetString and any textual + * conventions, like DisplayString, InternationalDisplayString or DateAndTime. + *

    + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/03/23 14:54:10 $ + */ +public interface AsnOctetsPrintableFace +{ + static final String version_id = + "@(#)$Id: AsnOctetsPrintableFace.java,v 3.5 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Returns whether or not the AsnOctets' byte array represent a printable + * string or not. + * + * @see AsnOctets#toCalendar() + * @see AsnOctets#toDisplayString() + * @see AsnOctets#toHex() + * @see AsnOctets#toString() + */ +public boolean isPrintable(byte[] value); + + + +/** + * This method provides the implemantation of the + * InternationalDisplayString text-convention. See + * HOST-RESOURCES-MIB. + * + *

    + * "This data type is used to model textual information + * in some character set. A network management station + * should use a local algorithm to determine which + * character set is in use and how it should be + * displayed. Note that this character set may be + * encoded with more than one octet per symbol, but will + * most often be NVT ASCII. When a size clause is + * specified for an object of this type, the size refers + * to the length in octets, not the number of symbols." + *

    + */ +public String toInternationalDisplayString(byte[] value); + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnPduSequence.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnPduSequence.java new file mode 100644 index 0000000..c9f89f0 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnPduSequence.java @@ -0,0 +1,144 @@ +// NAME +// $RCSfile: AsnPduSequence.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +/** + * The AsnPduSequence class know how a Pdu v1 and v2c is build, it knows its + * sequence. + * + * @author Tim Panton + * @version $Revision: 3.10 $ $Date: 2006/01/17 17:43:54 $ + */ +class AsnPduSequence extends AsnSequence +{ + private static final String version_id = + "@(#)$Id: AsnPduSequence.java,v 3.10 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + boolean snmpv3Discovery = false; + + AsnPduSequence(InputStream in, int len, int pos) throws IOException + { + super(in,len,pos); + } + + int getReqId() + { + AsnInteger rid = (AsnInteger) getObj(0); + return(rid.getValue()); + } + + int getWhatError() + { + AsnInteger estat = (AsnInteger) getObj(1); + return (estat.getValue()); + } + + int getWhereError() + { + AsnInteger estat = (AsnInteger) getObj(2); + return (estat.getValue()); + } + + AsnSequence getVarBind() + { + return (AsnSequence) getObj(3); + } + + /** + * recursively look for a pduSequence object + * - got one :-) + */ + AsnObject findPdu() + { + return this; + } + + int getValue() + { + AsnSequence varBind = (AsnSequence) getObj(3); + AsnSequence varPair = (AsnSequence) varBind.getObj(0); + AsnInteger val = (AsnInteger) varPair.getObj(1); + int value = val.getValue(); + + return value; + } + + boolean hadError() + { + return (SNMP_ERR_NOERROR != getWhatError()); + } + + boolean isSnmpv3Discovery() + { + return snmpv3Discovery; + } + + void setSnmpv3Discovery(boolean b) + { + snmpv3Discovery = b; + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnPrimitive.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnPrimitive.java new file mode 100644 index 0000000..dac43d7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnPrimitive.java @@ -0,0 +1,145 @@ +// NAME +// $RCSfile: AsnPrimitive.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +/** + * This class represents the Exception values for SNMP v2c, v3: + * SNMP_VAR_NOSUCHOBJECT, SNMP_VAR_NOSUCHINSTANCE, SNMP_VAR_ENDOFMIBVIEW + * + * @author Birgit Arkesteijn + * @version $Revision: 3.10 $ $Date: 2006/01/17 17:43:54 $ + * @see #SNMP_VAR_NOSUCHOBJECT + * @see #SNMP_VAR_NOSUCHINSTANCE + * @see #SNMP_VAR_ENDOFMIBVIEW + */ +public class AsnPrimitive extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnPrimitive.java,v 3.10 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + private byte type; + + /** + * Default Constructor. + * + * @param t The primitive type + * @see #SNMP_VAR_NOSUCHOBJECT + * @see #SNMP_VAR_NOSUCHINSTANCE + * @see #SNMP_VAR_ENDOFMIBVIEW + */ + public AsnPrimitive(byte t) + { + type = t; + } + + /** + * Returns the string representation of the AsnPrimitive. + * + * @return The string of the AsnPrimitive + */ + public String toString() + { + String str = "AsnPrimitive "; + if (type == SNMP_VAR_NOSUCHOBJECT) + { + str = "No such object"; + } + else if (type == SNMP_VAR_NOSUCHINSTANCE) + { + str = "No such instance"; + } + else if (type == SNMP_VAR_ENDOFMIBVIEW) + { + str = "End of MIB view"; + } + return str; + } + + void write(OutputStream out, int pos) throws IOException + { + AsnBuildHeader(out, type, 0); + } + + + /** + * Compares this object to the specified object. The result is + * true if and only if the argument is not + * null and is an AsnPrimitive object that + * contains the same type as this object. + * + * @param obj the object to compare with. + * @return true if the objects are the same; + * false otherwise. + */ + public boolean equals(Object obj) + { + if (obj instanceof AsnPrimitive) + { + return type == ((AsnPrimitive)obj).type; + } + return false; + } + + + /** + * Returns a hash code for this AsnPrimitive. + * + * @return a hash code value for this object, equal to the + * type represented by this + * AsnPrimitive object. + */ + public int hashCode() + { + return (int) type; + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnSequence.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnSequence.java new file mode 100644 index 0000000..ee04554 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnSequence.java @@ -0,0 +1,291 @@ +// NAME +// $RCSfile: AsnSequence.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.15 $ +// CREATED +// $Date: 2006/11/29 16:35:29 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + + +/** + * This class represents the ASN.1 sequence class. + * This class contains a Sequence of AsnObjects. + * + * @author Tim Panton + * @version $Revision: 3.15 $ $Date: 2006/11/29 16:35:29 $ + */ +class AsnSequence extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnSequence.java,v 3.15 2006/11/29 16:35:29 birgit Exp $ Copyright Westhawk Ltd"; + + private Vector children; + + /** + * Constructors. + */ + AsnSequence() + { + this(CONS_SEQ); + } + + /** + * Constructors. + */ + AsnSequence(byte oddtype) + { + type = oddtype; + children = new Vector(1, 1); + } + + + /** + * Constructors. + * @param pos The position of the first child + */ + AsnSequence(InputStream in, int len, int pos) throws IOException + { + this(); + if (debug > 10) + { + System.out.println("AsnSequence(): Length = " + len + + ", Pos = " + pos); + } + AsnObject a = null; + while (true) + { + a = AsnReadHeader(in, pos); + if (a != null) + { + pos += (a.headerLength + a.contentsLength); + add(a); + } + else + { + break; // all done + } + } + } + + /** + * Returns the string representation of the AsnSequence. + * + * @return The string of the AsnSequence + */ + public String toString() + { + return ""; + } + + /** + * Adds a child to the sequence. + */ + AsnObject add(AsnObject child) + { + if (child.isCorrect == true) + { + children.addElement(child); + } + return child; + } + + /** + * Replaces one child by the other. + * This is used by v3 to insert the security / auth fingerprint. + */ + AsnObject replaceChild(AsnObject oldChild, AsnObject newChild) + { + AsnObject ret = oldChild; + int at = children.indexOf(oldChild); + if (at > -1) + { + children.setElementAt(newChild, at); + ret = newChild; + } + return ret; + } + + /** + * Returns the total size of the children. + */ + int size() throws EncodingException + { + Enumeration childList = children.elements(); + int cnt, sz = 0; + + while(childList.hasMoreElements()) + { + // Get size of child + cnt = ((AsnObject)childList.nextElement()).size(); + + // Add space for type byte & length encoding + cnt += (1+getLengthBytes(cnt)); + sz += cnt; + } + return sz; + } + + void write(OutputStream out) + throws IOException, EncodingException + { + write(out, 0); + } + void write(OutputStream out, int pos) + throws IOException, EncodingException + { + // Output header + int length = size(); + startPos = pos; + AsnBuildHeader(out, type, length); + if (debug > 10) + { + System.out.println("\tAsnSequence.write(): begin, startPos = " + + startPos); + } + + // Output children + pos += headerLength; + Enumeration childList = children.elements(); + while(childList.hasMoreElements()) + { + AsnObject child = ((AsnObject)childList.nextElement()); + child.write(out, pos); + child.startPos = pos; + pos += child.headerLength + child.contentsLength; + } + + if (debug > 10) + { + System.out.println("\tAsnSequence.write(): end"); + } + } + + + /** + * recursively look for a pduSequence object. + */ + AsnObject findPdu() + { + AsnObject res = null; + + Enumeration childList = children.elements(); + while(childList.hasMoreElements()) + { + AsnObject child = ((AsnObject)childList.nextElement()); + res = child.findPdu(); + if (res != null) + { + break; + } + } + + if (this.isCorrect == false && res != null) + { + res.isCorrect = false; + } + return res; + } + + /** + * recursively look for a trapPduv1Sequence object. + */ + AsnObject findTrapPduv1() + { + AsnObject res = null; + + Enumeration childList = children.elements(); + while(childList.hasMoreElements()) + { + AsnObject child = ((AsnObject)childList.nextElement()); + res = child.findTrapPduv1(); + if (res != null) + { + break; + } + } + if (this.isCorrect == false && res != null) + { + res.isCorrect = false; + } + return res; + } + + AsnObject getObj(int offset) + { + AsnObject res = new AsnNull(); + try + { + res = (AsnObject) children.elementAt(offset); + } + catch (ArrayIndexOutOfBoundsException exc) + { + } + return res; + } + + int getObjCount() + { + return children.size(); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnTrapPduv1Sequence.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnTrapPduv1Sequence.java new file mode 100644 index 0000000..6c1f574 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnTrapPduv1Sequence.java @@ -0,0 +1,191 @@ +// NAME +// $RCSfile: AsnTrapPduv1Sequence.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.6 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +/** + * The AsnTrapPduv1Sequence class knows how a TrapPdu v1 is build, it knows its + * sequence. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.6 $ $Date: 2006/01/17 17:43:54 $ + */ +class AsnTrapPduv1Sequence extends AsnSequence +{ + private static final String version_id = + "@(#)$Id: AsnTrapPduv1Sequence.java,v 3.6 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +AsnTrapPduv1Sequence(InputStream in, int len, int pos) throws IOException +{ + super(in,len,pos); +} + +String getEnterprise() throws DecodingException +{ + String ent = ""; + AsnObject obj = getObj(0); + if (obj instanceof AsnObjectId) + { + AsnObjectId rid = (AsnObjectId) obj; + ent = rid.getValue(); + } + else + { + String msg = "TrapPduv1.Enterprise should be AsnObjectId" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return ent; +} + + +byte [] getIPAddress() throws DecodingException +{ + byte [] ip = null; + AsnObject obj = getObj(1); + if (obj instanceof AsnOctets) + { + AsnOctets estat = (AsnOctets) obj; + ip = estat.getBytes(); + } + else + { + String msg = "TrapPduv1.IPAddress should be of type AsnOctets" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return ip; +} + +int getGenericTrap() throws DecodingException +{ + int genTrap = -1; + AsnObject obj = getObj(2); + if (obj instanceof AsnInteger) + { + AsnInteger estat = (AsnInteger) obj; + genTrap = estat.getValue(); + } + else + { + String msg = "TrapPduv1.GenericTrap should be of type AsnInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return genTrap; +} + + +int getSpecificTrap() throws DecodingException +{ + int specTrap = -1; + AsnObject obj = getObj(3); + if (obj instanceof AsnInteger) + { + AsnInteger estat = (AsnInteger) obj; + specTrap = estat.getValue(); + } + else + { + String msg = "TrapPduv1.SpecificTrap should be of type AsnInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return specTrap; + +} + +long getTimeTicks() throws DecodingException +{ + long ticks = -1; + AsnObject obj = getObj(4); + if (obj instanceof AsnUnsInteger) + { + AsnUnsInteger estat = (AsnUnsInteger) obj; + ticks = estat.getValue(); + } + else + { + String msg = "TrapPduv1.TimeTicks should be of type AsnUnsInteger" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return ticks; +} + +AsnSequence getVarBind() throws DecodingException +{ + AsnSequence varb = null; + AsnObject obj = getObj(5); + if (obj instanceof AsnSequence) + { + varb = (AsnSequence) obj; + } + else + { + String msg = "TrapPduv1.VarBind should be of type AsnSequence" + + " instead of " + obj.getRespTypeString(); + throw new DecodingException(msg); + } + return varb; +} + +/** + * recursively look for a trapPduv1Sequence object + * - got one :-) + */ +AsnObject findTrapPduv1() +{ + return this; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger.java new file mode 100644 index 0000000..de59ab7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger.java @@ -0,0 +1,275 @@ +// NAME +// $RCSfile: AsnUnsInteger.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.16 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + + +/** + * This class represents ASN.1 32-bit unsigned integer. It is used for + * TIMETICKS, COUNTER, GAUGE. + * + * @see SnmpConstants#TIMETICKS + * @see SnmpConstants#COUNTER + * @see SnmpConstants#GAUGE + * + * @author Tim Panton + * @version $Revision: 3.16 $ $Date: 2006/01/17 17:43:54 $ + */ +public class AsnUnsInteger extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnUnsInteger.java,v 3.16 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The internal value of AsnUnsInteger. + */ + protected long value; + + /** + * Constructor. The type of the AsnUnsInteger defaults to TIMETICKS. + * + * @param v The value of the AsnUnsInteger + * @see SnmpConstants#TIMETICKS + */ + public AsnUnsInteger(long v) + { + this(v, TIMETICKS); + } + + /** + * Constructor to create a specific type of AsnUnsInteger. + * + * @param v The value of the AsnUnsInteger + * @param t The type of the AsnUnsInteger + * @see SnmpConstants#TIMETICKS + * @see SnmpConstants#COUNTER + * @see SnmpConstants#GAUGE + */ + public AsnUnsInteger(long v, byte t) + { + this.value = v; + this.type = t; + } + + + /** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnUnsInteger + */ + public AsnUnsInteger(InputStream in, int len) throws IOException + { + byte data[] = new byte[len]; + if (len != in.read(data,0,len)) + { + throw new IOException("AsnUnsInteger(): Not enough data"); + } + long val = bytesToLong(data); + this.value = val; + } + + /** + * Returns the value representation of the AsnUnsInteger. + * + * @return The value of the AsnUnsInteger + */ + public long getValue() + { + return value; + } + + /** + * Returns the string representation of the AsnUnsInteger. + * + * @return The string of the AsnUnsInteger + */ + public String toString() + { + return (String.valueOf(value)); + } + + /** + * Returns the number of bytes the integer occupies. + */ + int size() + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // 32-bit integer.. change to 56 to write 64-bit long + // loop through bytes in value while it is 'empty' + for(count=24; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + + // Check sign bit.. make sure negative's MSB bit is 1, + // positives is 0 + // (0x00000080 = 0x00 0x80) 0xFFFFFF01 => 0xFF 0x01 + // (0x0000007F = 0x7F) 0xFFFFFF80 => 0x80 + if (((value >> count) & 0x80) != sign) count += 8; + return (count>>3)+1; + } + + + /** + * Output integer. + */ + void write(OutputStream out, int pos) throws IOException + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // Get count + for(count=24; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + if (((value >> count) & 0x80) != sign) count += 8; + + // Build header and write value + AsnBuildHeader(out, type, (count>>3)+1); + + if (debug > 10) + { + System.out.println("\tAsnUnsInteger(): value = " + value + + ", pos = " + pos); + } + + for(; count>=0; count-=8) + { + out.write((byte)((value >> count) & 0xFF)); + } + } + + /** + * Changes an array of bytes into a long. + * Thanks to Julien Conan (jconan@protego.net) for improving + * this method. + * + * @param data the array of bytes + * @return the int representation of the array + */ + protected long bytesToLong(byte[] data) throws IOException + { + DataInputStream dis = new DataInputStream( + new ByteArrayInputStream(data)); + + long val = 0; + int size = data.length; + + for (int n=0; ntrue if and only if the argument is not + * null and is an AsnUnsInteger object that + * contains the same long value as this object. + * + * @param obj the object to compare with. + * @return true if the objects are the same; + * false otherwise. + */ + public boolean equals(Object obj) + { + if (obj instanceof AsnUnsInteger) + { + return value == ((AsnUnsInteger)obj).value; + } + return false; + } + + + /** + * Returns a hash code for this AsnUnsInteger. + * + * @return a hash code value for this object, equal to the + * hash of the primitive long value represented + * by this AsnUnsInteger object. + */ + public int hashCode() + { + // nicked from Long.hashCode + return (int)(value ^ (value >>> 32)); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger64.java b/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger64.java new file mode 100644 index 0000000..cc010e8 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/AsnUnsInteger64.java @@ -0,0 +1,257 @@ +// NAME +// $RCSfile: AsnUnsInteger64.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.16 $ +// CREATED +// $Date: 2009/03/05 13:11:33 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + * original version by hargrave@dellgate.us.dell.com (Jordan Hargrave) + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + + +/** + * This class represents ASN.1 64-bit unsigned integer. It is used for + * COUNTER64. + * + * @see SnmpConstants#COUNTER64 + * + * @author Tim Panton + * @version $Revision: 3.16 $ $Date: 2009/03/05 13:11:33 $ + */ +public class AsnUnsInteger64 extends AsnObject +{ + private static final String version_id = + "@(#)$Id: AsnUnsInteger64.java,v 3.16 2009/03/05 13:11:33 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * The internal value of AsnUnsInteger64. + */ + // TODO: move to BigInteger, since long is too small + protected long value; + + /** + * Constructor. + * + * @param v The value of the AsnUnsInteger64 + */ + public AsnUnsInteger64(long v) + { + this.value = v; + this.type = COUNTER64; + } + + + /** + * Constructor. + * + * @param in The input stream from which the value should be read + * @param len The length of the AsnUnsInteger64 + */ + public AsnUnsInteger64(InputStream in, int len) throws IOException + { + byte data[] = new byte[len]; + if (len != in.read(data,0,len)) + { + throw new IOException("AsnUnsInteger64(): Not enough data"); + } + this.value = bytesToLong(data); + } + + /** + * Returns the value representation of the AsnUnsInteger64. + * + * @return The value of the AsnUnsInteger64 + */ + public long getValue() + { + return value; + } + + /** + * Returns the string representation of the AsnUnsInteger64. + * + * @return The string of the AsnUnsInteger64 + */ + public String toString() + { + return (String.valueOf(value)); + } + + /** + * Returns the number of bytes the integer occupies. + */ + int size() + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // 64-bit integer.. change to 24 to write 32-bit long + // loop through bytes in value while it is 'empty' + for(count=56; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + + // Check sign bit.. make sure negative's MSB bit is 1, + // positives is 0 + // (0x00000080 = 0x00 0x80) 0xFFFFFF01 => 0xFF 0x01 + // (0x0000007F = 0x7F) 0xFFFFFF80 => 0x80 + if (((value >> count) & 0x80) != sign) count += 8; + + return (count>>3)+1; + } + + + /** + * Output integer. + */ + void write(OutputStream out, int pos) throws IOException + { + int count, empty = 0x00, sign = 0x00; + + if (value < 0) + { + empty = 0xFF; + sign = 0x80; + } + + // Get count + for(count=56; count>0; count-=8) + { + if ( ((value >> count) & 0xFF) != empty) break; + } + if (((value >> count) & 0x80) != sign) count += 8; + + // Build header and write value + AsnBuildHeader(out, COUNTER64, (count>>3)+1); + if (debug > 10) + { + System.out.println("\tAsnUnsInteger64(): value = " + value + + ", pos = " + pos); + } + for(; count>=0; count-=8) + { + out.write((byte)((value >> count) & 0xFF)); + } + } + + /** + * Changes an array of bytes into a long. + * Thanks to Julien Conan (jconan@protego.net) for improving + * this method. + * + * @param data the array of bytes + * @return the int representation of the array + */ + protected long bytesToLong(byte[] data) throws IOException + { + DataInputStream dis = new DataInputStream( + new ByteArrayInputStream(data)); + + long val = 0; + int size = data.length; + + for (int n=0; ntrue if and only if the argument is not + * null and is an AsnUnsInteger64 object that + * contains the same long value as this object. + * + * @param obj the object to compare with. + * @return true if the objects are the same; + * false otherwise. + */ + public boolean equals(Object obj) + { + if (obj instanceof AsnUnsInteger64) + { + return value == ((AsnUnsInteger64)obj).value; + } + return false; + } + + + /** + * Returns a hash code for this AsnUnsInteger64. + * + * @return a hash code value for this object, equal to the + * hash of the primitive long value represented + * by this AsnUnsInteger64 object. + */ + public int hashCode() + { + // nicked from Long.hashCode + return (int)(value ^ (value >>> 32)); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/BitsHelper.java b/src/main/java/uk/co/westhawk/snmp/stack/BitsHelper.java new file mode 100644 index 0000000..f9a264c --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/BitsHelper.java @@ -0,0 +1,175 @@ +// NAME +// $RCSfile: BitsHelper.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.1 $ +// CREATED +// $Date: 2006/03/23 15:09:48 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; + +/** + * This class help with the BITS construct. The AsnOctets class is + * growing too big, because of all the different representations. + * + * Note that BITS is different from the ANS.1 BIT STRING. Apparently BIT + * STRING was in v1, but was depreceated in favour of BITS. + * + *
    + * An instance with bits 0, 3 and 10 set will have the value:
    + *
    + *      10010000 00100000
    + *      ^  ^       ^
    + * bit  0  3      10
    + *
    + * so will consist of the two bytes (octets) 0x90 & 0x20.
    + * 
    + * + * See also + * section 7.1.4. of + * SNMPv2-SMI + * and section 8. (3) of + * SNMPv2-TM. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.1 $ $Date: 2006/03/23 15:09:48 $ + * @since 5_0 + */ +public class BitsHelper +{ + private static final String version_id = + "@(#)$Id: BitsHelper.java,v 3.1 2006/03/23 15:09:48 birgit Exp $ Copyright Westhawk Ltd"; + + +/** + * Sets or unsets the flag (bit) on the specified index. The bit + * will be set to zero if toset is false, set to one if toset is + * true. + * + * Note, as a side effect the size of the asn octet might grow. + * + * @param oct The AsnOctets that represents the BITS + * @param index The index (0 - X) + * @param toset Whether to set (true) or unset (false) the bit + */ +public static void setFlagged(AsnOctets oct, int index, boolean toset) +throws IllegalArgumentException +{ + if (index < 0) + { + throw new IllegalArgumentException("Illegal value index (" + index + + "). Shoud be greater than 0."); + } + else + { + byte mask; + int byteNo = index / 8; + int bitNo = index % 8; + + // See if we've got enough bytes in our array. + // Reallocate if necessary. + int len = oct.value.length; + if (byteNo >= len) + { + int newLen = byteNo+1; + byte[] newValue = new byte[newLen]; + System.arraycopy(oct.value, 0, newValue, 0, len); + oct.value = newValue; + } + + if (toset == true) + { + mask = (byte) (0x80 >>> bitNo); + oct.value[byteNo] = (byte) (oct.value[byteNo] | mask); + } + else + { + mask = (byte) (0x7F >>> bitNo); + oct.value[byteNo] = (byte) (oct.value[byteNo] & mask); + } + } +} + + +/** + * Returns if the flag (bit) on the specified index is set. The bit + * will be set to zero if toset is false, set to one if toset is + * true. + * + * @param oct The AsnOctets that represents the BITS + * @param index The index (0 - X) + * @return Whether the bit is set (true) or unset (false) + */ +public static boolean isFlagged(AsnOctets oct, int index) +throws IllegalArgumentException +{ + boolean isFlagged = false; + if (index < 0) + { + throw new IllegalArgumentException("Illegal value index (" + index + + "). Shoud be greater than 0."); + } + else + { + byte mask; + int byteNo = index / 8; + int bitNo = index % 8; + + int len = oct.value.length; + if (byteNo < len) + { + // Shift the bit we're interested in to the far left. + // If the bit is one, the byte will be negative. + byte res = (byte) (oct.value[byteNo] << bitNo); + isFlagged = (res < 0); + } + } + return isFlagged; +} + + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/DecodingException.java b/src/main/java/uk/co/westhawk/snmp/stack/DecodingException.java new file mode 100644 index 0000000..dd22717 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/DecodingException.java @@ -0,0 +1,84 @@ +// NAME +// $RCSfile: DecodingException.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * Thrown to indicate that the response PDU cannot be decoded. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/01/17 17:43:54 $ + */ +public class DecodingException extends PduException +{ + private static final String version_id = + "@(#)$Id: DecodingException.java,v 3.5 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructs a DecodingException with no specified detail message. + * + */ +public DecodingException() +{ + super(); +} + +/** + * Constructs a DecodingException with the specified detail + * message. + * + * @param str The detail message. + */ +public DecodingException(String str) +{ + super(str); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/DefaultAsnOctetsPrintable.java b/src/main/java/uk/co/westhawk/snmp/stack/DefaultAsnOctetsPrintable.java new file mode 100644 index 0000000..dd7cae3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/DefaultAsnOctetsPrintable.java @@ -0,0 +1,140 @@ +// NAME +// $RCSfile: DefaultAsnOctetsPrintable.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * Default implementation of AsnOctetsPrintableFace. + * This class has no effect on the way AsnOctets with type IPADDRESS + * or OPAQUE are printed. + * + *

    + * When the type is ASN_OCTET_STR, the method tries to guess whether + * or not the string is printable; without the knowledge of the MIB + * it cannot distinguish between OctetString and any textual + * conventions, like DisplayString, InternationalDisplayString or DateAndTime. + *

    + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.3 $ $Date: 2006/01/17 17:43:54 $ + */ +public class DefaultAsnOctetsPrintable implements AsnOctetsPrintableFace +{ + static final String version_id = + "@(#)$Id: DefaultAsnOctetsPrintable.java,v 3.3 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +public DefaultAsnOctetsPrintable() +{ +} + +/** + * Returns whether or not the AsnOctets' byte array represent a printable + * string or not. + * + *

    + * This method can only make a rough guess. There is no way it always + * gets it right. + * It is much better to embed MIB knowledge in your implementation, and + * use toCalendar() or toDisplayString(), than calling toString(). + *

    + * + * @see AsnOctets#toCalendar() + * @see AsnOctets#toDisplayString() + * @see AsnOctets#toHex() + * @see AsnOctets#toString() + */ +public boolean isPrintable(byte[] value) +{ + int length = value.length; + int b = ' '; // the first printable char in the ASCII table + int e = '~'; // the last printable char in the ASCII table + + /* + * About the test for 'value[i] == 0': + * (Quote from one of our customers:) + * I've seen cases where there are embedded nulls in a sysdescr + * - not always at the end either - and we need to get complete + * data back from the device even in this situation. + */ + + boolean isPrintable = true; + int i=0; + while (i= b && value[i] <= e) + || + Character.isWhitespace((char)value[i]) + || + value[i] == 0); + i++; + } + + return isPrintable; +} + + +/** + * Returns the String according to the platform's default character set. + * + * @see AsnOctetsPrintableFace#toInternationalDisplayString(byte[] value) + */ +public String toInternationalDisplayString(byte[] value) +{ + String str = ""; + if (value.length > 0) + { + // this will use the platform's default charset. + str = new String(value).trim(); + } + return str; +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/DefaultTrapContext.java b/src/main/java/uk/co/westhawk/snmp/stack/DefaultTrapContext.java new file mode 100644 index 0000000..58c52bb --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/DefaultTrapContext.java @@ -0,0 +1,186 @@ +// NAME +// $RCSfile: DefaultTrapContext.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.12 $ +// CREATED +// $Date: 2009/03/05 13:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.net.*; +import uk.co.westhawk.snmp.util.*; + + +/** + * The DefaultTrapContext class will enable this stack to receive traps. + * Only one (1) instance of the DefaultTrapContext can exist. The + * context will only start receiving (or listen for) traps when there is + * at least one listener registered. Two kind of listeners can be added; + * the normal and unhandled trap listeners. + * The normal trap listeners are added via the + * addTrapListener() method, + * the unhandled trap listeners are added via the + * addUnhandledTrapListener(). + * + *

    + * Use one of the getInstance() methods to get the instance and add a trap + * listener. This class will fire undecoded trap events, i.e. the raw + * data is sent and no attempt is made to decode the data into a pdu. + *

    + * + *

    + * The SnmpContext classes provide functionality for decoded trap + * events. These classes will register themselves to the + * DefaultTrapContext object and only pass the event on if it matches + * their configuration. + *

    + * + *

    + * + * Note that because only one instance of this class + * can exist, the first call of getInstance() will define + * the settings + * (i.e. port number and socket type) for the lifetime of the stack. All + * the subsequent calls of getInstance() will return the existing + * instance, irrespective of the arguments. + *

    + * + *

    + * On UNIX and Linux operating systems the default port where trap are + * sent (i.e. 162) can only be opened as root. + *

    + * + *

    + * Note, this class is now deprecated. We are (very) slowly trying to + * move to a more general way of receiving packets and adding agent + * functionality. ListeningContext and ListeningContextPool allow the + * stack to listen to more than one port. + *

    + * + * @deprecated As of 4_14, replaced by {@link ListeningContext} and + * {@link ListeningContextPool} + * + * @see AbstractSnmpContext#addTrapListener + * @see ListeningContext + * @see ListeningContextPool + * + * @author Birgit Arkesteijn + * @version $Revision: 3.12 $ $Date: 2009/03/05 13:12:50 $ + */ +public class DefaultTrapContext extends ListeningContext +{ + private static final String version_id = + "@(#)$Id: DefaultTrapContext.java,v 3.12 2009/03/05 13:12:50 birgita Exp $ Copyright Westhawk Ltd"; + + private static DefaultTrapContext current = null; + +/** + * Constructor. + * The Standard socket type will be used. + * + * @param port The local port where traps are received + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +protected DefaultTrapContext(int port) throws IOException +{ + this(port, SnmpContextBasisFace.STANDARD_SOCKET); +} + +/** + * Constructor. + * + * The typeSocket will indicate which type of socket to use. This way + * different handlers can be provided. + * It should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param port The local port where traps are received + * @param typeSocketA The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +protected DefaultTrapContext(int port, String typeSocketA) +throws IOException +{ + super(port, typeSocketA); +} + + +/** + * Returns the instance of DefaultTrapContext. It will create the + * instance if it didn't exists. + * See the note above. + */ +public static synchronized DefaultTrapContext getInstance(int port) +throws IOException +{ + if (current == null) + { + current = new DefaultTrapContext(port); + } + return current; +} + +/** + * Returns the instance of DefaultTrapContext. It will create the + * instance if it didn't exists. + * See the note above. + */ +public static synchronized DefaultTrapContext getInstance(int port, String typeSocketA) +throws IOException +{ + if (current == null) + { + current = new DefaultTrapContext(port, typeSocketA); + } + return current; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/DefaultUsmAgent.java b/src/main/java/uk/co/westhawk/snmp/stack/DefaultUsmAgent.java new file mode 100644 index 0000000..316d706 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/DefaultUsmAgent.java @@ -0,0 +1,298 @@ +// NAME +// $RCSfile: DefaultUsmAgent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2009/03/05 15:51:42 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.beans.UsmDiscoveryBean; + +/** + * This implementation of UsmAgent tries to discover the parameters by + * doing the default USM discovery process on localhost. + * + *

    + * Note that it is not guaranteed that the agent will allow discovery + * by itself. Also, if the SNMP agent reboots while the stack is + * running, it will not pick up the new boots and time. + *

    + * + *

    + * Users are advised and encouraged to provide a better, more accurate + * implementation of UsmAgent. + *

    + * + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * @see SnmpContextv3 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.10 $ $Date: 2009/03/05 15:51:42 $ + */ +public class DefaultUsmAgent implements UsmAgent +{ + static final String version_id = + "@(#)$Id: DefaultUsmAgent.java,v 3.10 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * The default name of the local host, localhost. + */ + public final static String LOCAL_HOST = "localhost"; + + /** + * The default port number of the local host, 161. + */ + public final static int LOCAL_PORT = 161; + + private SnmpContextv3Basis context; + private String hostname; + private String hostaddress; + private int port; + +public DefaultUsmAgent() +{ + try + { + setAgentName(LOCAL_HOST); + } + catch (java.net.UnknownHostException exc) + { + hostname = LOCAL_HOST; + hostaddress = "127.0.0.1"; + } + setAgentPort(LOCAL_PORT); +} + +/** + * Returns the authoritative SNMP Engine ID. If the discovery failed, + * null will be returned. + * + * @return The Engine ID + */ +public String getSnmpEngineId() +{ + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(hostaddress, port); + return engineId; +} + +/** + * Returns the authoritative Engine Boots. If the discovery failed, + * 1 will be returned. + * + * @return The Engine Boots + */ +public int getSnmpEngineBoots() +{ + int boots = 1; + TimeWindowNode node = null; + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(hostaddress, port); + if (engineId != null) + { + node = tWindow.getTimeLine(engineId); + } + if (node != null) + { + boots = node.getSnmpEngineBoots(); + } + return boots; +} + +/** + * Returns the authoritative Engine Time. If the discovery failed, + * 1 will be returned. + * + * @return The Engine Time + */ +public int getSnmpEngineTime() +{ + int time = 1; + TimeWindowNode node = null; + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(hostaddress, port); + if (engineId != null) + { + node = tWindow.getTimeLine(engineId); + } + if (node != null) + { + time = node.getSnmpEngineTime(); + } + return time; +} + +/** + * Sets the SNMP context. It will do a discovery if needed. + */ +public void setSnmpContext(SnmpContextv3Basis c) +{ + context = c; + try + { + discoverIfNeeded(); + } + catch (PduException exc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".setSnmpContext(): " + + exc.getMessage()); + } + } + catch (java.io.IOException exc) + { + if (AsnObject.debug > 4) + { + System.out.println(getClass().getName() + ".setSnmpContext(): " + + exc.getMessage()); + } + } +} + +/** + * Sets my own hostname, i.e. the name of the agent or authoritative + * engine. By default localhost is used. + * Sets the hostaddress as well, using java.net.InetAddress. + * + * @see #LOCAL_HOST + * @exception java.net.UnknownHostException Thrown when java.net.InetAddress cannot + * resolve the name + */ +public void setAgentName(String host) +throws java.net.UnknownHostException +{ + hostname = host; + java.net.InetAddress ipAddr = java.net.InetAddress.getByName(hostname); + hostaddress = ipAddr.getHostAddress(); +} + +/** + * Sets my own port number, i.e. the port number of the agent + * or authoritative engine. By default 161 is used. + * + * @see #LOCAL_PORT + */ +public void setAgentPort(int p) +{ + port = p; +} + +/** + * This discovers the USM timeliness of hostname and port as set by + * setAgentName() and setAgentPort(), but with all the other details + * taken from the SNMPv3 context. + * + * @see #setAgentName + * @see #setAgentPort + */ +void discoverIfNeeded() +throws java.io.IOException, PduException +{ + UsmDiscoveryBean discBean = null; + boolean isNeeded = false; + + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(hostaddress, port); + if (engineId == null) + { + isNeeded = true; + discBean = new UsmDiscoveryBean(hostname, + port, context.getBindAddress(), context.getTypeSocket()); + } + + if (context.isUseAuthentication()) + { + if (isNeeded) + { + discBean.setAuthenticationDetails(context.getUserName(), + context.getUserAuthenticationPassword(), + context.getAuthenticationProtocol()); + } + else if (tWindow.isTimeLineKnown(engineId) == false) + { + isNeeded = true; + discBean = new UsmDiscoveryBean( + hostname, port, context.getBindAddress(), + context.getTypeSocket()); + discBean.setAuthenticationDetails(context.getUserName(), + context.getUserAuthenticationPassword(), + context.getAuthenticationProtocol()); + } + + if (isNeeded && context.isUsePrivacy()) + { + discBean.setPrivacyDetails(context.getUserPrivacyPassword(), + context.getPrivacyProtocol()); + } + } + + if (isNeeded) + { + discBean.startDiscovery(); + discBean.freeResources(); + } +} + +/** + * @since 4_14 + */ +public long getUsmStatsUnknownEngineIDs() +{ + return 0; +} + +/** + * @since 4_14 + */ +public long getUsmStatsNotInTimeWindows() +{ + return 0; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/EncodingException.java b/src/main/java/uk/co/westhawk/snmp/stack/EncodingException.java new file mode 100644 index 0000000..5956be2 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/EncodingException.java @@ -0,0 +1,83 @@ +// NAME +// $RCSfile: EncodingException.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * Thrown to indicate that the PDU cannot be build or encoded. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/01/17 17:43:54 $ + */ +public class EncodingException extends PduException +{ + private static final String version_id = + "@(#)$Id: EncodingException.java,v 3.5 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructs an EncodingException with no specified detail message. + */ +public EncodingException() +{ + super(); +} + +/** + * Constructs an EncodingException with the specified detail + * message. + * + * @param str The detail message. + */ +public EncodingException(String str) +{ + super(str); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/GetBulkPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/GetBulkPdu.java new file mode 100644 index 0000000..a6ed843 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/GetBulkPdu.java @@ -0,0 +1,195 @@ +// NAME +// $RCSfile: GetBulkPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.17 $ +// CREATED +// $Date: 2006/02/09 14:30:19 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +/** + * This class represents the SNMP GetBulk Pdu. This request has been + * added in SNMPv2c, hence is not supported by SNMPv1 agents. + * + *

    + * The request is processed on the agent side in the following way: + *

    + * // getNext (once) on the non_repeaters
    + * for (n=0; n<N; n++)
    + * {
    + *    getNext(var[n]);
    + * }
    + * // getNext (max_repetitions times) on the repeaters
    + * for (m=1; m<M; m++)
    + * {
    + *     for (r=1; r<R; r++)
    + *     {
    + *         getNext(var[N+r]);
    + *     }
    + * }
    + * 
    + * + *

    + * Where:
    + *

      + *
    • L is the number of vars in the request
    • + *
    • N = Max(Min(non_repeaters, L), 0)
    • + *
    • M = Max(max_repetitions, 0)
    • + *
    • R = L-N
    • + *
    + * + * @author Birgit Arkesteijn + * @version $Revision: 3.17 $ $Date: 2006/02/09 14:30:19 $ + */ +public class GetBulkPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: GetBulkPdu.java,v 3.17 2006/02/09 14:30:19 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The value of the non_repeaters. + */ + protected int non_repeaters = 0; + /** + * The value of the max_repetitions. + */ + protected int max_repetitions = 0; + +/** + * Constructor. + * The GetBulkRequest has been added in SNMPv2. Its purpose is to + * retrieve a large amount of information with one request. + * + * @param con The context (v2c or v3) of the Pdu + */ +public GetBulkPdu(SnmpContextBasisFace con) +{ + super(con); + setMsgType(AsnObject.GETBULK_REQ_MSG); +} + +/** + * Sets the non_repeaters. The non_repeaters specifies the number of + * variables in the varbind list for which a single lexicographic + * successor is to be returned. + * If they are not set, the value will be 0 (zero). + */ +public void setNonRepeaters(int no) +{ + // same field as error status in any other PDU. + non_repeaters = no; +} + +/** + * Returns the non_repeaters. + */ +public int getNonRepeaters() +{ + return non_repeaters; +} + +/** + * Sets the max_repetitions. The max_repetitions specifies the number of + * lexicographic successors to be returned for the remaining variables + * in the varbind list. + * If they are not set, the value will be 0 (zero). + */ +public void setMaxRepetitions(int no) +{ + // same field as error index in any other PDU. + max_repetitions = no; +} + +/** + * Old method to set the max_repetitions. Was a spelling mistake, + * it is still in here for backwards compatibility. + * + * @deprecated Use {@link #setMaxRepetitions(int no)}. + * @see #setMaxRepetitions + */ +public void setMaxRepititions(int no) +{ + setMaxRepetitions(no); +} + +/** + * Returns the max_repetitions. + */ +public int getMaxRepetitions() +{ + return max_repetitions; +} + +/** + * Sends the Pdu. + * + *

    + * The GetBulk request has the same format as any other request, except + * that the error_status field is replaced by non_repeaters and the + * error_index field is replaces by max_repetitions. + *

    + * @see Pdu#send(int, int) + */ +public boolean send() throws java.io.IOException, PduException +{ + return send(non_repeaters, max_repetitions); +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer(super.toString()); + int l = buffer.length(); + buffer.setLength(l-1); + + buffer.append(", non_rep=").append(getNonRepeaters()); + buffer.append(", max_rep=").append(getMaxRepetitions()); + buffer.append("]"); + return buffer.toString(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/GetNextPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/GetNextPdu.java new file mode 100644 index 0000000..dafcae1 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/GetNextPdu.java @@ -0,0 +1,89 @@ +// NAME +// $RCSfile: GetNextPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.8 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the SNMP GetNext Pdu. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.8 $ $Date: 2006/01/17 17:43:54 $ + * @see uk.co.westhawk.snmp.pdu.OneGetNextPdu + * @see uk.co.westhawk.snmp.pdu.GetNextPdu_vec + */ +public class GetNextPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: GetNextPdu.java,v 3.8 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * Constructor. + * + * @param con The context of the Pdu + */ + public GetNextPdu(SnmpContextBasisFace con) + { + super(con); + setMsgType(AsnObject.GETNEXT_REQ_MSG); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/GetPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/GetPdu.java new file mode 100644 index 0000000..c913203 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/GetPdu.java @@ -0,0 +1,77 @@ +// NAME +// $RCSfile: GetPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/01/17 17:59:34 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the (public) SNMP Get Pdu. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.3 $ $Date: 2006/01/17 17:59:34 $ + * @see uk.co.westhawk.snmp.pdu.OneGetPdu + * @see uk.co.westhawk.snmp.pdu.GetPdu_vec + */ +public class GetPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: GetPdu.java,v 3.3 2006/01/17 17:59:34 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * Constructor. + * + * @param con The context of the Pdu + */ + public GetPdu(SnmpContextBasisFace con) + { + super(con); + setMsgType(AsnObject.GET_REQ_MSG); + } + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/InformPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/InformPdu.java new file mode 100644 index 0000000..6a51876 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/InformPdu.java @@ -0,0 +1,97 @@ +// NAME +// $RCSfile: InformPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/11/29 16:23:33 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2002 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the SNMP Inform Request Pdu. This request has + * been added in SNMPv2c, hence is not supported by SNMPv1 agents. + * + *

    + * Inform Requests + * are sent between managers. It is an acknowlegded trap since + * the receiving end should send a Response Pdu as reply. + * The varbind list has the same elements as the TrapPduv2.
    + * See SNMPv2-PDU + *

    + * + *

    + * Note this PDU should be sent to port 162 (the default trap port) by + * default. You will have to create a SnmpContext with the + * ListeningContextFace.DEFAULT_TRAP_PORT as parameter! + *

    + * + *

    + * For SNMPv3: The sender of an inform PDU acts as the authoritative engine. + *

    + * + * @see TrapPduv2 + * @see ListeningContextFace#DEFAULT_TRAP_PORT + * @since 4_12 + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/11/29 16:23:33 $ + */ +public class InformPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: InformPdu.java,v 3.5 2006/11/29 16:23:33 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructor. + * + * @param con The context (v2c or v3) of the Pdu + */ +public InformPdu(SnmpContextBasisFace con) +{ + super(con); + setMsgType(AsnObject.INFORM_REQ_MSG); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/ListeningContext.java b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContext.java new file mode 100644 index 0000000..a810919 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContext.java @@ -0,0 +1,568 @@ +// NAME +// $RCSfile: ListeningContext.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.12 $ +// CREATED +// $Date: 2009/03/05 13:24:00 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.io.*; +import java.util.*; + +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.net.*; +import uk.co.westhawk.snmp.util.*; + + +/** + * The ListeningContext class will enable this stack to receive packets. + * This class replaces the deprecated DefaultTrapContext class. + * The context will only start receiving (or listen for) packets when there is + * at least one listener registered. + * + *

    + * Two kind of listeners can be added; + * the normal and unhandled PDU listeners. + * The normal PDU listeners are added via the + * addRawPduListener() method, + * the unhandled PDU listeners are added via the + * addUnhandledRawPduListener(). + * Both these listeners provide undecoded events. + *

    + * + *

    + * The SnmpContext classes provide functionality for decoded PDU and + * trap events. These classes will register themselves via the + * addRawPduListener() to the ListeningContext object and + * only pass the (decoded) event on if it matches their configuration. + *

    + * + *

    + * On UNIX and Linux operating systems the default port where PDUs and + * traps are sent (i.e. 161 and 162) can only be opened + * as root. + *

    + * + *

    + * Only one process can listen on a certain port. To prevent more than + * one ListeningContext listening on the same port, use the + * ListeningContextPool class. + *

    + * + * @see ListeningContextPool + * @see AbstractSnmpContext#addTrapListener + * @see AbstractSnmpContext#addRequestPduListener + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.12 $ $Date: 2009/03/05 13:24:00 $ + */ +public class ListeningContext implements ListeningContextFace, Runnable +{ + private static final String version_id = + "@(#)$Id: ListeningContext.java,v 3.12 2009/03/05 13:24:00 birgita Exp $ Copyright Westhawk Ltd"; + + private Object soc_lock = new Object(); + // thanks to Nick Sheen nsheen@tippingpoint.com for pointing out that "" is interned by the VM + private static int counter; + private ContextSocketFace soc; + private Thread me; + private String basename; + private volatile boolean stopRequested; + // thanks to Nick Sheen nsheen@tippingpoint.com for pointing out that volatile is needed here + + protected int maxRecvSize; + protected String typeSocket; + protected int hostPort; + protected String bindAddr; + + transient private RawPduReceivedSupport pduSupport, unhandledSupport; + +/** + * Constructor, using the Standard socket type. + * + * @param port The local port where packets are received + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +public ListeningContext(int port) +{ + this(port, null, SnmpContextBasisFace.STANDARD_SOCKET); +} + +/** + * Constructor, using the Standard socket type. + * + * If bindAddress is null, it will accept connections on + * any/all local addresses. If you want to listen to + *
      + *
    • + * IPv4 only interfaces, use address "0.0.0.0" + *
    • + *
    • + * IPv6 only interfaces, use address "::" + *
    • + *
    + * + * @param port The local port where packets are received + * @param bindAddress The local address the server will bind to + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +public ListeningContext(int port, String bindAddress) +{ + this(port, bindAddress, SnmpContextBasisFace.STANDARD_SOCKET); +} + +/** + * Constructor. + * + * If bindAddress is null, it will accept connections on + * any/all local addresses. If you want to listen to + *
      + *
    • + * IPv4 only interfaces, use address "0.0.0.0" + *
    • + *
    • + * IPv6 only interfaces, use address "::" + *
    • + *
    + * + * + * The typeSocketA will indicate which type of socket to use. This way + * different handlers can be provided. + * This parameter should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + *

    + * Note, the TCP_SOCKET does not provide functionality to send a + * response back. Listening on such a socket is only useful when + * listening for traps. + *

    + * + * @param port The local port where packets are received + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public ListeningContext(int port, String bindAddress, String typeSocketA) +{ + hostPort = port; + bindAddr = bindAddress; + typeSocket = typeSocketA; + + basename = ""+hostPort+"_"+bindAddr; + + pduSupport = new RawPduReceivedSupport(this); + unhandledSupport = new RawPduReceivedSupport(this); + maxRecvSize = SnmpContextBasisFace.MSS; +} + + +public int getPort() +{ + return hostPort; +} + +public String getBindAddress() +{ + return bindAddr; +} + +public String getTypeSocket() +{ + return typeSocket; +} + + +public int getMaxRecvSize() +{ + return maxRecvSize; +} +public void setMaxRecvSize(int no) +{ + maxRecvSize = no; +} + +/** + * This method will stop the thread listening for packets. + * All transmitters, PDUs in flight and traplisteners will be removed + * when run() finishes. + * + *

    + * It closes the socket. + * The thread will actually stop/finish when the run() finishes. Since + * the socket is closed, the run() will fall through almost instantly. + *

    + * + *

    + * Note that by calling this method the whole stack will stop listening + * for packets on this particular port! The listeners added via the + * SnmpContext classes are affected as well. + *

    + * + *

    + * When you add a new listener, the context will start listening again. + *

    + * + *

    + * Note: The thread(s) will not die immediately; this will take about + * half a minute. + *

    + */ +public void destroy() +{ + synchronized(soc_lock) + { + stopRequested = true; + if (soc != null) + { + if (AsnObject.debug > 12) + { + System.out.println(getClass().getName() + ".destroy(): Closing socket "); + } + soc.close(); + } + } +} + +/** + * We wait for any incoming PDUs and fire a rawpdu received (undecoded) event + * if we do. + + *

    + * The undecoded events are fired to all normal listeners (added via + * addRawPduListener()), until one of them consumes it. + * The SnmpContext classes will consume the event if it matches their + * configuration. + *

    + * + *

    + * If none of them consume the event, the undecoded events are fired to + * all unhandled PDU listeners (added via addUnhandledRawPduListener()), + * until one of them consumes it. + *

    + * + * @see RawPduReceivedSupport#fireRawPduReceived + * @see #addRawPduListener(RawPduListener) + * @see #addUnhandledRawPduListener(RawPduListener) + */ +public void run() +{ + // while It is visible + while (!stopRequested) + { + // block for incoming packets + me.yield(); + try + { + if (stopRequested) + { + break; + } + + StreamPortItem item = soc.receive(maxRecvSize); + ByteArrayInputStream in = item.getStream(); + + String hostAddress = item.getHostAddress(); + int port = item.getHostPort(); + + // read the bytes of the input stream into bu + int nb = in.available(); + byte [] bu = new byte[nb]; + in.read(bu); + in.close(); + + if (AsnObject.debug > 10) + { + SnmpUtilities.dumpBytes(getClass().getName() + + ".run(): Received from " + + hostAddress + + ", from port " + port + + ": ", bu); + } + KickProcessIncomingMessage thread = + new KickProcessIncomingMessage(hostAddress, port, bu); + thread.start(); + } + catch (IOException exc) + { + if (exc instanceof InterruptedIOException) + { + if (AsnObject.debug > 15) + { + System.out.println(getClass().getName() + ".run(): Idle recv " + exc.getMessage()); + } + } + else + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".run(): IOException: " + exc.getMessage()); + } + } + } + catch (Exception exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".run(): Exception: " + exc.getMessage()); + exc.printStackTrace(); + } + } + catch (Error err) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".run(): Error: " + err.getMessage()); + err.printStackTrace(); + } + } + } + + me = null; + soc = null; + pduSupport.empty(); + unhandledSupport.empty(); +} + +public void addRawPduListener(RawPduListener listener) +throws IOException +{ + synchronized(soc_lock) + { + pduSupport.addRawPduListener(listener); + startListening(); + } +} + +public void removeRawPduListener(RawPduListener listener) +{ + synchronized(soc_lock) + { + pduSupport.removeRawPduListener(listener); + destroyIfNoListeners(); + } +} + +public void addUnhandledRawPduListener(RawPduListener listener) +throws IOException +{ + synchronized(soc_lock) + { + unhandledSupport.addRawPduListener(listener); + startListening(); + } +} + +public void removeUnhandledRawPduListener(RawPduListener listener) +{ + synchronized(soc_lock) + { + unhandledSupport.removeRawPduListener(listener); + destroyIfNoListeners(); + } +} + +/** + * Creates the socket and starts listening for PDUs if we didn't do so + * already. + * This method is called in addRawPduListener() and + * addUnhandledRawPduListener(). + * + * @exception IOException Thrown when the socket cannot be created. + * @see #addRawPduListener + * @see #addUnhandledRawPduListener + */ +private void startListening() +throws IOException +{ + if (soc == null) + { + // create tempSoc first, so that when 'create' fails, soc + // will remain null. + ContextSocketFace tempSoc = AbstractSnmpContext.getSocket(typeSocket); + if (tempSoc != null) + { + tempSoc.create(hostPort, bindAddr); + soc = tempSoc; + + if (AsnObject.debug > 12) + { + System.out.println(getClass().getName() + ".startListening()" + + ": soc.getLocalSocketAddress() = " + soc.getLocalSocketAddress()); + System.out.println(getClass().getName() + ".startListening()" + + ": soc.getRemoteSocketAddress() = " + soc.getRemoteSocketAddress()); + } + } + } + if (me == null) + { + stopRequested = false; + me = new Thread(this, basename+"_Listen"); + me.setPriority(me.NORM_PRIORITY); + me.start(); + } +} + + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for the pool of contexts. + * + * @return The hash key + */ +public String getHashKey() +{ + String str = hostPort + + "_" + bindAddr + + "_" + typeSocket; + return str; +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer("ListeningContext["); + buffer.append("port=").append(hostPort); + buffer.append(", bindAddress=").append(bindAddr); + buffer.append(", socketType=").append(typeSocket); + buffer.append(", #rawPduListeners=").append(pduSupport.getListenerCount()); + buffer.append(", #rawPduUnhandledListeners=").append(unhandledSupport.getListenerCount()); + buffer.append("]"); + return buffer.toString(); +} + +/** + * Processes an incoming packet. + * + * @see #run + */ +protected void processIncomingMessage(String hostAddress, + int port, byte [] bu) throws DecodingException, IOException +{ + AsnDecoderBase rpdu = new AsnDecoderBase(); + ByteArrayInputStream in = new ByteArrayInputStream(bu); + AsnSequence asnTopSeq = rpdu.getAsnSequence(in); + int version = rpdu.getSNMPVersion(asnTopSeq); + + boolean isConsumed = pduSupport.fireRawPduReceived(version, hostAddress, port, bu); + if (isConsumed == false) + { + unhandledSupport.fireRawPduReceived(version, hostAddress, port, bu); + } +} + + +/** + * Only destroy this object when there are no more listeners. + * + * Thanks to Jeremy Stone (Jeremy.Stone@cyclone-technology.com). + * @since 6.1 + */ +private void destroyIfNoListeners() +{ + if (pduSupport.getListenerCount() == 0 + && unhandledSupport.getListenerCount() == 0) + { + destroy(); + } +} + +class KickProcessIncomingMessage extends Thread +{ + /** + * This class makes sure that dealing with an incoming packet is + * done at a separate thread so the ListeningContext can go back + * listening immediately. + * This will at some point be replaced by a Thread pool of + * some kind. + */ + private String hostAddress; + private int port; + private byte [] bu; + + KickProcessIncomingMessage(String newHostAddress, int newPort, + byte [] newBu) + { + hostAddress = newHostAddress; + port = newPort; + bu = newBu; + this.setPriority(Thread.MIN_PRIORITY); + this.setName(newHostAddress + "_" + newPort + + "_KickProcessIncomingMessage_" + counter); + counter++; + } + + public void run() + { + try + { + processIncomingMessage(hostAddress, port, bu); + } + catch (IOException exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".run(): IOException: " + exc.getMessage()); + } + } + catch (DecodingException exc) + { + if (AsnObject.debug > 1) + { + System.out.println(getClass().getName() + ".run(): DecodingException: " + exc.getMessage()); + } + } + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextFace.java b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextFace.java new file mode 100644 index 0000000..147c2fc --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextFace.java @@ -0,0 +1,184 @@ +// NAME +// $RCSfile: ListeningContextFace.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.6 $ +// CREATED +// $Date: 2006/11/29 16:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.event.*; + +/** + * This interface contains the SNMP listening context methods. + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.6 $ $Date: 2006/11/29 16:12:50 $ + */ +public interface ListeningContextFace +{ + static final String version_id = + "@(#)$Id: ListeningContextFace.java,v 3.6 2006/11/29 16:12:50 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The default port number where we listen for traps (162). + */ + public final static int DEFAULT_TRAP_PORT = 162; + + +/** + * Returns the port number. + * + * @return The port no + */ +public int getPort(); + +/** + * Returns the local address the server will bind to + * When the address is null, the socket accepts connections on + * any/all local addresses. + * + * @return The bind address + */ +public String getBindAddress(); + +/** + * Returns the type of socket. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @return The type of socket + */ +public String getTypeSocket(); + +/** + * Returns the maximum number of bytes this context will read from the + * socket. By default this will be set to MSS (i.e. 1300). + * + * @see SnmpContextBasisFace#MSS + * @see #setMaxRecvSize(int) + * @see AbstractSnmpContext#setMaxRecvSize(int) + * @return The number + */ +public int getMaxRecvSize(); + +/** + * Sets the maximum number of bytes this context will read from the + * socket. By default this will be set to MSS (i.e. 1300). + * + * @see SnmpContextBasisFace#MSS + * @see AbstractSnmpContext#getMaxRecvSize() + * @param no The new size + */ +public void setMaxRecvSize(int no); + +/** + * Removes the resouces held by this context. + * This method will stop the thread listening for packets. + */ +public void destroy(); + +/** + * Adds the specified PDU listener to receive the undecoded PDUs. + * When a PDU is received the PDU received event is fired to all + * listeners, until one of them consumes it. + * + *

    + * All the SnmpContext objects use this method to listen for PDUs. When + * a SnmpContext object decodes the PDU succesfully, it will consume + * it. + *

    + * + *

    + * Only when a listener is added will this context create a listening socket. + *

    + * + * @param l The listener object + * @exception java.io.IOException Thrown when creating a listening + * socket fails + * + * @see RawPduReceivedSupport#fireRawPduReceived + * @see AbstractSnmpContext#addTrapListener + * @see AbstractSnmpContext#addRequestPduListener + * @see #addUnhandledRawPduListener(RawPduListener) + */ +public void addRawPduListener(RawPduListener l) +throws java.io.IOException; + +/** + * Removes the specified PDU listener. When there are no more listeners, + * calls destroy(). + * + * @param l The listener object + */ +public void removeRawPduListener(RawPduListener l); + +/** + * Adds the specified PDU listener to receive the undecoded PDUs when + * it was not handled (i.e. not consumed) by any of the PDU listeners in + * addRawPduListener(). + * + *

    + * Only when a listener is added will this context create a listening socket. + *

    + * + * @param listener The listener object + * @exception java.io.IOException Thrown when creating a listening + * socket fails + * + * @see #addRawPduListener(RawPduListener) + */ +public void addUnhandledRawPduListener(RawPduListener listener) +throws java.io.IOException; + +/** + * Removes the specified unhandled PDU listener. When there are no more + * listeners, calls destroy(). + * + * @param listener The listener object + */ +public void removeUnhandledRawPduListener(RawPduListener listener); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextPool.java b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextPool.java new file mode 100644 index 0000000..6044fc3 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/ListeningContextPool.java @@ -0,0 +1,505 @@ +// NAME +// $RCSfile: ListeningContextPool.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.7 $ +// CREATED +// $Date: 2009/03/05 13:27:41 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.event.*; + +/** + * This class contains the pool of listening contexts. The usage of this + * class will prevent more than one ListeningContext trying to listen to + * the same port. + * + * @see ListeningContext + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.7 $ $Date: 2009/03/05 13:27:41 $ + */ +public class ListeningContextPool implements ListeningContextFace +{ + private static final String version_id = + "@(#)$Id: ListeningContextPool.java,v 3.7 2009/03/05 13:27:41 birgita Exp $ Copyright Westhawk Ltd"; + + protected static Hashtable contextPool; + + protected ListeningContext context = null; + protected String socketType; + protected String bindAddr; + protected int hostPort; + +/** + * Constructor, using the Standard socket type. + * + * @param port The local port where packets are received + * + * @see #ListeningContextPool(int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +public ListeningContextPool(int port) +{ + this(port, null, SnmpContextBasisFace.STANDARD_SOCKET); +} + + +/** + * Constructor, using the Standard socket type. + * + * If bindAddress is null, it will accept connections on + * any/all local addresses. If you want to listen to + *
      + *
    • + * IPv4 only interfaces, use address "0.0.0.0" + *
    • + *
    • + * IPv6 only interfaces, use address "::" + *
    • + *
    + * + * @param port The local port where packets are received + * @param bindAddress The local address the server will bind to + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + */ +public ListeningContextPool(int port, String bindAddress) +{ + this(port, bindAddress, SnmpContextBasisFace.STANDARD_SOCKET); +} + + +/** + * Constructor. + * + * If bindAddress is null, it will accept connections on + * any/all local addresses. If you want to listen to + *
      + *
    • + * IPv4 only interfaces, use address "0.0.0.0" + *
    • + *
    • + * IPv6 only interfaces, use address "::" + *
    • + *
    + * + * The typeSocket will indicate which type of socket to use. This way + * different handlers can be provided. + * + *

    + * Note, the TCP_SOCKET does not provide functionality to send a + * response back. Listening on such a socket is only useful when + * listening for traps. + *

    + * + * @param port The local port where packets are received + * @param bindAddress The local address the server will bind to + * @param typeSocket The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public ListeningContextPool(int port, String bindAddress, String typeSocket) +{ + initPools(); + hostPort = port; + bindAddr = bindAddress; + socketType = typeSocket; + + context = getMatchingContext(); +} + +private static synchronized void initPools() +{ + if (contextPool == null) + { + contextPool = new Hashtable(5); + } +} + +public int getPort() +{ + return hostPort; +} + +public String getBindAddress() +{ + return bindAddr; +} + +public String getTypeSocket() +{ + return socketType; +} + +public int getMaxRecvSize() +{ + int res = SnmpContextBasisFace.MSS; + if (context != null) + { + res = context.getMaxRecvSize(); + } + return res; +} + +/** + * Sets the maximum number of bytes this context will read from the + * socket. By default this will be set to MSS (i.e. 1300). + * Only the current context will be affected, not to all the + * contexts in the pool. + * + * @param no The new size + * + * @see SnmpContextBasisFace#MSS + * @see AbstractSnmpContext#getMaxRecvSize() + */ +public void setMaxRecvSize(int no) +{ + if (context == null) + { + context = getMatchingContext(); + } + context.setMaxRecvSize(no); +} + +/** + * Destroys the current context. + * + *

    + * Note that by calling this method the whole stack will stop listening + * for packets on the port this context was listening on! The listeners + * added via the SnmpContext classes are affected as well. + *

    + * + * @see #destroyPool() + * @see ListeningContextPool#destroy() + */ +public void destroy() +{ + synchronized(contextPool) + { + if (context != null) + { + String hashKey = context.getHashKey(); + + int count = 0; + Item item = (Item) contextPool.get(hashKey); + + if (item != null) + { + count = item.getCounter(); + count--; + item.setCounter(count); + } + + if (count <=0) + { + contextPool.remove(hashKey); + context.destroy(); + } + context = null; + } + } +} + +/** + * Destroys all the contexts in the pool and empties the pool. + * + *

    + * Note that by calling this method the whole stack will stop listening + * for any packets! The listeners added via the + * SnmpContext classes are affected as well. + *

    + * + * @see #destroy() + */ +public void destroyPool() +{ + Hashtable copyOfPool = null; + + synchronized(contextPool) + { + synchronized(contextPool) + { + copyOfPool = (Hashtable) contextPool.clone(); + } + contextPool.clear(); + } + context = null; + + Enumeration keys = copyOfPool.keys(); + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + Item item = (Item) copyOfPool.get(key); + if (item != null) + { + ListeningContext cntxt = (ListeningContext) item.getContext(); + cntxt.destroy(); + } + } + copyOfPool.clear(); +} + +/** + * Returns a context from the pool. + * This methods checks for an existing context that matches all our + * properties. If such a context does not exist, a new one is created and + * added to the pool. + * + * @return A context from the pool + * @see #getHashKey + */ +protected ListeningContext getMatchingContext() +{ + Item item = null; + ListeningContext newContext = null; + String hashKey = getHashKey(); + + destroy(); + synchronized(contextPool) + { + int count=0; + if (contextPool.containsKey(hashKey)) + { + item = (Item) contextPool.get(hashKey); + newContext = item.getContext(); + count = item.getCounter(); + } + else + { + newContext = new ListeningContext(hostPort, bindAddr, socketType); + item = new Item(newContext); + contextPool.put(hashKey, item); + } + count++; + item.setCounter(count); + } + return newContext; +} + +/** + * Dumps the pool of contexts. This is for debug purposes. + * @param title The title of the dump + */ +public void dumpContexts(String title) +{ + Hashtable copyOfPool = null; + synchronized(contextPool) + { + copyOfPool = (Hashtable) contextPool.clone(); + } + + System.out.println(title + " " + copyOfPool.size()); + Enumeration keys = copyOfPool.keys(); + int i=0; + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + Item item = (Item) copyOfPool.get(key); + + if (item != null) + { + int count = item.getCounter(); + ListeningContext cntxt = item.getContext(); + + System.out.println("\tcontext: " + key + ", count: " + count + + ", index: " + i + ", " + cntxt.toString()); + if (cntxt == context) + { + System.out.println("\t\tcurrent context"); + } + i++; + } + } +} + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for the pool of contexts. + * + * @return The hash key + */ +public String getHashKey() +{ + String str = hostPort + + "_" + bindAddr + + "_" + socketType; + return str; +} + +public void addRawPduListener(RawPduListener l) +throws java.io.IOException +{ + if (context != null) + { + context.addRawPduListener(l); + } +} +public void removeRawPduListener(RawPduListener l) +{ + if (context != null) + { + context.removeRawPduListener(l); + } +} + + +/** + * Removes the specified PDU listener from all the contexts in the pool. + * + * @see ListeningContext#removeRawPduListener + */ +public void removeRawPduListenerFromPool(RawPduListener l) +{ + Hashtable copyOfPool = null; + + if (contextPool != null) + { + synchronized(contextPool) + { + copyOfPool = (Hashtable) contextPool.clone(); + } + + Enumeration keys = copyOfPool.keys(); + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + Item item = (Item) copyOfPool.get(key); + + if (item != null) + { + ListeningContext cntxt = item.getContext(); + cntxt.removeRawPduListener(l); + } + } + } +} + + +public void addUnhandledRawPduListener(RawPduListener l) +throws java.io.IOException +{ + if (context != null) + { + context.addUnhandledRawPduListener(l); + } +} +public void removeUnhandledRawPduListener(RawPduListener l) +{ + if (context != null) + { + context.removeUnhandledRawPduListener(l); + } +} + + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + String res = ""; + if (context != null) + { + res = context.toString(); + } + return res; +} + + +class Item +{ + private ListeningContext context = null; + private int counter = 0; + + /** + * Constructor. + * + * @param con The context + */ + Item(ListeningContext con) + { + context = con; + counter = 0; + } + + + ListeningContext getContext() + { + return context; + } + + int getCounter() + { + return counter; + } + + void setCounter(int i) + { + counter = i; + } + + /** + * Returns a string representation of the object. + * @return The string + */ + public String toString() + { + StringBuffer buffer = new StringBuffer("Item["); + buffer.append("context=").append(context.toString()); + buffer.append(", counter=").append(counter); + buffer.append("]"); + return buffer.toString(); + } +} // end Item + + +} // end ListeningContextPool + + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/MultiResponsePdu.java b/src/main/java/uk/co/westhawk/snmp/stack/MultiResponsePdu.java new file mode 100644 index 0000000..0e32db2 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/MultiResponsePdu.java @@ -0,0 +1,347 @@ +// NAME +// $RCSfile: MultiResponsePdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2007/10/17 10:44:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; + + +/** + * This class can receive multiple responses. + * Typical usage includes sending a single PDU to a multicast / + * broadcast address so that multiple responses can be received from + * different sources. + * + *

    + * This class sets a single long timeout for the retry, so it sends the + * request only once. + * Opposite to its parent class, this class does not ignore the duplicate + * responses, and it will timeout by nature. + *

    + * + *

    Note:

    + *
      + *
    • Please realise that you might choke the stack and your network, when + * you use this class, even on a small subnet
    • + *
    • This PDU will eat up transmit and receive resources, until it times out
    • + *
    • This PDU cannot be used to receive traps
    • + *
    • Authentication (and privacy) is by definition a unicast activity. + * You can find unauthenticated SNMPv3 engines, by broadcasting this PDU + * with a SnmpContextv3(Pool) with no authentication. + * Then you need to continue an authentication/privacy context and a (normal) + * PDU.
      + * In other words, finding SNMPv3 engines that only support + * authentication and/or privacy cannot be done via broadcasting. + *
    • + *
    + * + * + *

    + * Thanks to Josh Bers <jbers@bbn.com> + *

    + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.3 $ $Date: 2007/10/17 10:44:09 $ + */ +public class MultiResponsePdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: MultiResponsePdu.java,v 3.3 2007/10/17 10:44:09 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * Hashtable to hold responses received from agents. + */ + private Hashtable responses = new Hashtable(); + + /** + * IP address of current response + */ + private String thisIP = null; + + + /** + * By default create a MultiResponsePdu that will wait for 3 + * seconds for responses to come in from multiple sources. If you + * want to wait longer set the RetryInterval to a longer first + * timeout. To make the request more reliable, add more timeouts. + * + * @param con The context + */ + public MultiResponsePdu(SnmpContextBasisFace con) + { + super(con); + setRetryIntervals(new int[]{3000}); + } + + + /** + * Gets the IP address of the host of the most recent response received. + * + * @return The sourceAgent value + */ + public String getSourceAgent() + { + return thisIP; + } + + + /** + * Gets the number of responses so far received + * to this request. + * + * @return The number of responses + */ + public int getNumResponses() + { + return responses.size(); + } + + + /** + * Prints out the list of received responses and their source IP + * addressses. Results will be ommitted if not yet received. + * + * @return String representation of this PDU and all its received + * responses + */ + public String toString() + { + // loop over vector of responses and use Pdu.toString(boolean) + // to print out the received varbinds. + StringBuffer buffer = new StringBuffer(); + if (!answered) + { + buffer.append(toString(false)); + } + else + { + Enumeration ipaddrs = responses.keys(); + String ipaddr = (String) ipaddrs.nextElement(); + // set respVarbinds to each response in turn calling toString(true) + respVarbinds = (Vector) responses.get(ipaddr); + + buffer.append(toString(true)); + buffer.append(" rhost=").append(ipaddr); + int i=2; + while (ipaddrs.hasMoreElements()) + { + ipaddr = (String) ipaddrs.nextElement(); + respVarbinds = (Vector) responses.get(ipaddr); + + buffer.append("\n\t"); + buffer.append(printVars("respVarbinds"+i, respVarbinds)); + buffer.append(" rhost=").append(ipaddr); + i++; + } + } + return buffer.toString(); + } + + + /** + * Lets the observers know which source we received a response from. + */ + protected void tell_them() + { + String sender = thisIP; + // if timed out then we are done waiting for replies. + if (isTimedOut()) + { + sender = null; + } + else + { + // record this response for posterity + responses.put(sender, respVarbinds); + } + + // tell all interested parties + notifyObservers(sender); + + // free up space for next result + respVarbinds = null; + thisIP = null; + } + + + + + /** + * Fills in the received response. + * + * Now override fillin to fetch source ip address and not set answered + * you can get multiple responses by setting the timeout period long + * do this in the constructor. + * + * @param seq Description of Parameter + * @see Pdu#getResponseVarbinds() + */ + void fillin(AsnPduSequence seq) + { + // this will be set to true (eventually) in handleNoAnswer() + if (answered) + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".fillin(): " + + "Got a second answer to request " + getReqId()); + } + return; + } + + // check that we haven't already heard from this host before: + thisIP = getContext().getReceivedFromHostAddress(); + if (responses.containsKey(thisIP)) + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".fillin(): " + + "Got a second answer from " + thisIP + + " to request " + getReqId()); + } + return; + } + + // fillin(null) can be called in case of a Decoding exception + if (seq != null) + { + if (seq.isCorrect == true) + { + int n = -1; + try + { + // Fill in the request id + this.req_id = seq.getReqId(); + setErrorStatus(seq.getWhatError()); + setErrorIndex(seq.getWhereError()); + + // The varbinds from the response/report are set in a + // new Vector. + AsnSequence varBind = seq.getVarBind(); + int size = varBind.getObjCount(); + respVarbinds = new Vector(size, 1); + for (n=0; nwww.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class contains the SNMP v1 context that is needed by a Pdu to + * send a SNMP v1 request in environments where thread creation is + * unwanted. + * + *

    + * This extends SnmpContext so that it does not create any + * threads to send PDUs. It must be used with the + * PDU class PassiveTrapPduv1. The original purpose of the + * Passive classes is to allow the stack to be used in environments where + * thread creation is unwanted, eg database JVMs such as Oracle JServer. + * See SNMPv2-PDU. + *

    + * + *

    + * See + * notes + * on how to send traps in an Oracle JServer environment. + *

    + * + * @see uk.co.westhawk.snmp.pdu.PassiveTrapPduv1 + * @since 4_12 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.10 $ $Date: 2009/03/05 13:12:50 $ + */ +public class PassiveSnmpContext extends SnmpContext +{ + private static final String version_id = + "@(#)$Id: PassiveSnmpContext.java,v 3.10 2009/03/05 13:12:50 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @see SnmpContext#SnmpContext(String, int) + */ +public PassiveSnmpContext(String host, int port) +throws java.io.IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The type of socket to use. + * + * @see SnmpContext#SnmpContext(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public PassiveSnmpContext(String host, int port, String typeSocketA) +throws java.io.IOException +{ + super(host, port, typeSocketA); +} + + +/** + * Constructor. + * + * If bindAddress is null, then the system will pick up a valid local + * address to bind the socket. + * + * The typeSocketA will indicate which type of socket to use. This way + * different handlers can be provided. + * It should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @exception java.io.IOException Thrown when the socket cannot be + * created. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +protected PassiveSnmpContext(String host, int port, String bindAddress, String typeSocketA) +throws java.io.IOException +{ + super(host, port, bindAddress, typeSocketA); +} + + +/** + * Overrides the AbstractSnmpContext.activate() to do nothing. + * This prevents the creation of threads in the base class. + * + * @see AbstractSnmpContext#activate() + */ +protected void activate() +{ + // do nothing +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/PassiveSnmpContextv2c.java b/src/main/java/uk/co/westhawk/snmp/stack/PassiveSnmpContextv2c.java new file mode 100644 index 0000000..72415fa --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/PassiveSnmpContextv2c.java @@ -0,0 +1,158 @@ +// NAME +// $RCSfile: PassiveSnmpContextv2c.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2009/03/05 13:12:50 $ +// COPYRIGHT +// ERG Group Ltd +// TO DO +// + +/* + * Copyright (C) 2001 by ERG Group Ltd + * www.erggroup.com + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Mike Waters + */ + + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class contains the SNMP v2c context that is needed by every Pdu to + * send a SNMP v2c request in environments where thread creation is + * unwanted. + * + *

    + * This extends SnmpContextv2c so that it does not create any + * threads to send PDUs. It must be used with the + * PDU class PassiveTrapPduv2. The original purpose of the + * Passive classes is to allow the stack to be used in environments where + * thread creation is unwanted, eg database JVMs such as Oracle JServer. + * See SNMPv2-PDU. + *

    + * + *

    + * See + * notes + * on how to send traps in an Oracle JServer environment. + *

    + * + * @see uk.co.westhawk.snmp.pdu.PassiveTrapPduv2 + * @since 4_12 + * + * @author Mike Waters, ERG Group + * @version $Revision: 3.10 $ $Date: 2009/03/05 13:12:50 $ + */ +public class PassiveSnmpContextv2c extends SnmpContextv2c +{ + private static final String version_id = + "@(#)$Id: PassiveSnmpContextv2c.java,v 3.10 2009/03/05 13:12:50 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @see SnmpContextv2c#SnmpContextv2c(String, int) + */ +public PassiveSnmpContextv2c(String host, int port) +throws java.io.IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The type of socket to use. + * + * @see SnmpContextv2c#SnmpContextv2c(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public PassiveSnmpContextv2c(String host, int port, String typeSocketA) +throws java.io.IOException +{ + super(host, port, typeSocketA); +} + +/** + * Constructor. + * + * If bindAddress is null, then the system will pick up a valid local + * address to bind the socket. + * + * The typeSocketA will indicate which type of socket to use. This way + * different handlers can be provided. + * It should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @exception java.io.IOException Thrown when the socket cannot be + * created. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +protected PassiveSnmpContextv2c(String host, int port, String bindAddress, String typeSocketA) +throws java.io.IOException +{ + super(host, port, bindAddress, typeSocketA); +} + + +/** + * Overrides the AbstractSnmpContext.activate() to do nothing. + * This prevents the creation of threads in the base class. + * + * @see AbstractSnmpContext#activate() + */ +protected void activate() +{ + // do nothing +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/Pdu.java b/src/main/java/uk/co/westhawk/snmp/stack/Pdu.java new file mode 100644 index 0000000..63d0e12 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/Pdu.java @@ -0,0 +1,994 @@ +// NAME +// $RCSfile: Pdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.33 $ +// CREATED +// $Date: 2008/12/12 14:55:51 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.util.*; +import java.io.*; + +import uk.co.westhawk.snmp.util.*; + +/** + * This class represents the ASN PDU object, this is the equivalent of + * a GetRequest PDU. + * + * @author Tim Panton + * @version $Revision: 3.33 $ $Date: 2008/12/12 14:55:51 $ + */ +public abstract class Pdu extends Observable +{ + private static final String version_id = + "@(#)$Id: Pdu.java,v 3.33 2008/12/12 14:55:51 tpanton Exp $ Copyright Westhawk Ltd"; + + protected Vector reqVarbinds = null; + protected Vector respVarbinds = null; + + private final static String TIMED_OUT = "Timed out"; + private final static String [] errorStrings = + { + "No error", + "Value too big error", + "No such name error", + "Bad value error", + "Read only error", + "General error", + "No access error", + "Wrong type error", + "Wrong length error", + "Wrong encoding error", + "Wrong value error", + "No creation error", + "Inconsistent value error", + "Resource unavailable error", + "Commit failed error", + "Undo failed error", + "Authorization error", + "Not writable error", + "Inconsistent name error", + }; + + private static int next_id = 1; + private static final Object NEXT_ID_LOCK= new Object(); + + private int retry_intervals[] = {500,1000,2000,5000,5000}; + + protected byte[] encodedPacket = null; + protected SnmpContextBasisFace context; + protected boolean added = false; + protected byte msg_type; + + int req_id; + protected Integer snmpv3MsgId = null; + protected int errstat; + protected int errind; + + private Transmitter trans = null; + private int retries; + protected boolean answered; + private boolean got = false; + private boolean isTimedOut; + private PduException respException = null; + +/** + * The value of the response is set. This will be called by + * Pdu.fillin(). + */ +protected void new_value(int n, varbind res) {} + +/** + * This method notifies all observers. + * This will be called by Pdu.fillin(). + * + *

    + * The Object to the update() method of the Observer will be a varbind, + * unless an exception occurred. + * In the case of an exception, that exception will be passed. + * So watch out casting! + *

    + */ +protected void tell_them() +{ + notifyObservers(); +} + +/** + * Constructor. + * + * @param con The context of the PDU + * @see SnmpContext + * @see SnmpContextv2c + * @see SnmpContextv3 + */ +public Pdu(SnmpContextBasisFace con) +{ + context = con; + + // TODO: would not work if we ever were to send response or report! + // TODO: We would have to set the req_id! + + // Added NEXT_ID_LOCK on suggestion of + // Victor Kirk + synchronized(NEXT_ID_LOCK) + { + req_id = next_id++; + } + errstat = AsnObject.SNMP_ERR_NOERROR; + errind = 0x00; + reqVarbinds = new Vector(1,1); + setMsgType(AsnObject.GET_REQ_MSG); + isTimedOut = false; + + // if it is not set to false, PDUs that do not receive a response + // will not be filled in properly. + answered = false; +} + +/** + * Returns the context of this PDU. + * @return The context + */ +public SnmpContextBasisFace getContext() +{ + return context; +} + +/** + * Sets the retry intervals of the PDU. The length of the array + * corresponds with the number of retries. Each entry in the array + * is the number of milliseconds of each try. + * + *

    + * If used, please set before sending! + *

    + * + * The default is {500, 1000, 2000, 5000, 5000}. + * It is good practice to make the interval bigger with each retry, + * if the numbers are the same the chance of collision is higher. + * + * @param rinterval The interval in msec of each retry + */ +public void setRetryIntervals(int rinterval[]) +{ + retry_intervals = rinterval; +} + +public int[] getRetryIntervals() +{ + return retry_intervals; +} + +/** + * Sends the PDU. + * Note that all properties of the context have to be set before this + * point. + */ +public boolean send() throws IOException, PduException +{ + return send(errstat, errind); +} + +/** + * Sends the PDU. This method accommodates the GetBulk request. + * + * @param error_status The value of the error_status field. + * @param error_index The value of the error_index field. + * @see #send() + */ +protected boolean send(int error_status, int error_index) +throws IOException, PduException +{ + if (added == false) + { + // Moved this statement from the constructor because it + // conflicts with the way the SnmpContextXPool works. + added = context.addPdu(this); + } + Enumeration vbs = reqVarbinds.elements(); + encodedPacket = context.encodePacket(msg_type, req_id, error_status, + error_index, vbs, snmpv3MsgId); + addToTrans(); + return added; +} + +/** + * Adds the PDU to its transmitter. The transmitter is the thread that + * will be sent the PDU and then waits for the answer. + * + * @see #send + */ +protected void addToTrans() +{ + if (added && (trans != null)) + { + // thanks to Ian Dowse for synchronisation + synchronized(trans) + { + trans.setPdu(this); + trans.stand(); + } + } +} + +/** + * Sends the actual packet and updates the retries. + * + * @see AbstractSnmpContext#sendPacket(byte[] p) + */ +protected boolean sendme() +{ + context.sendPacket(encodedPacket); + retries ++; + + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".sendme(): Sent Pdu reqId=" + req_id + ", retries "+retries); + } + return (retries > 3); +} + + +/** + * Sends the PDU. + * For backwards compatibility only. Please use send() instead. + * The community name will be passed to the SnmpContext. If using + * SnmpContextv3, the community name will be ignored. + * + * @param com The community name of the PDU in SNMPv1 and SNMPv2c. + * @deprecated Community name has moved to SnmpContext. Use {@link SnmpContext#setCommunity(String)}. + * + * @see SnmpContext#setCommunity + * @see #send + */ +public boolean send(String com) throws IOException, PduException +{ + if (context instanceof SnmpContext) + { + ((SnmpContext)context).setCommunity(com); + } + return send(); +} + +/** + * Adds an OID (object identifier) to the PDU. The OID indicates which + * MIB variable we request for or which MIB variable should be set. + * + * @param oid The oid + * @see #addOid(varbind) + * @see varbind + */ +public void addOid(String oid) +{ + varbind vb = new varbind(oid); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU. The OID indicates which + * MIB variable we request for or which MIB variable should be set. + * + * @param oid The oid + * @see #addOid(varbind) + * @see varbind + * @since 4_12 + */ +public void addOid(AsnObjectId oid) +{ + varbind vb = new varbind(oid); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU and the value that has + * to be set. This method has moved from SetPdu to this class in version 4_12. + * + * @param oid The oid + * @param val The value + * @see Pdu#addOid + * @see varbind + * @since 4_12 + */ +public void addOid(String oid, AsnObject val) +{ + varbind vb = new varbind(oid, val); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU and the value that has + * to be set. + * + *

    + * Thanks to Eli Bishop (eli@graphesthesia.com) for the suggestion. + *

    + * + * @param oid The oid + * @param val The value + * @see Pdu#addOid + * @see varbind + * @since 4_12 + */ +public void addOid(AsnObjectId oid, AsnObject val) +{ + varbind vb = new varbind(oid, val); + addOid(vb); +} + +/** + * Adds an OID (object identifier) to the PDU. + * + * @param var The varbind + * @see #addOid(String) + */ +public void addOid(varbind var) +{ + reqVarbinds.addElement(var); +} + +/** + * Returns a copy of the varbinds used to build the request. + * + * @return the request varbinds of this PDU. + */ +public varbind[] getRequestVarbinds() +{ + int sz = reqVarbinds.size(); + varbind[] arr = new varbind[sz]; + reqVarbinds.copyInto(arr); + return arr; +} + +/** + * Returns a copy of the varbinds received in the response. + * If there was no response (yet), null will be returned. + * + * @return the response varbinds of this PDU. + * @exception PduException An agent or decoding exception occurred + * whilst receiving the response. + * + * @see #getErrorStatus + * @see #notifyObservers + */ +public varbind[] getResponseVarbinds() throws PduException +{ + if (respException != null) + { + throw respException; + } + + varbind[] arr = null; + if (respVarbinds != null) + { + int sz = respVarbinds.size(); + arr = new varbind[sz]; + respVarbinds.copyInto(arr); + } + return arr; +} + +private void dump(Vector v, varbind[] array) +{ + int sz = v.size(); + System.out.println("Vector: "); + for (int i=0; i 6) + { + System.out.println(getClass().getName() + ".setResponseException(): reqId=" + req_id + exc.getMessage()); + } + respException = exc; +} + +/** + * Returns the request id of the PDU. + * + * @return The ID + */ +public int getReqId() +{ + return req_id; +} + +/** + * Returns the error index. + * The error index indicates which of the OIDs went wrong. + * + * @return the error index + * @see #getErrorStatus + */ +public int getErrorIndex() +{ + return errind; +} + +/** + * Returns the error status as indicated by the error-status field in + * the reponse PDU. The error index will indicated which OID caused the + * error. + * In case of a decoding exception the error status + * will be set to one of the decoding errors: + *
      + *
    • + * SnmpConstants.SNMP_ERR_DECODING_EXC. + *
    • + *
    • + * SnmpConstants.SNMP_ERR_DECODINGASN_EXC. + *
    • + *
    • + * SnmpConstants.SNMP_ERR_DECODINGPKTLNGTH_EXC. + *
    • + *
    + * + *

    + * The actual exception will be passed to your + * update(Observable ob, Object arg) + * method via the the parameter + * arg. + *

    + * + * @return the error status + * @see #notifyObservers + * @see #getResponseVarbinds + * @see SnmpConstants#SNMP_ERR_NOERROR + * @see SnmpConstants#SNMP_ERR_DECODING_EXC + * @see SnmpConstants#SNMP_ERR_DECODINGASN_EXC + * @see SnmpConstants#SNMP_ERR_DECODINGPKTLNGTH_EXC + * @see #getErrorStatusString + * @see #getErrorIndex + */ +public int getErrorStatus() +{ + return errstat; +} + +/** + * Returns the string representation of the error status. + * + * @return the error string + * @see #getErrorStatus + */ +public String getErrorStatusString() +{ + String errString = ""; + if (errstat >= 0) + { + if (errstat < errorStrings.length) + { + errString = errorStrings[errstat]; + + if (errstat == AsnObject.SNMP_ERR_GENERR + && + isTimedOut() == true) + { + errString = TIMED_OUT; + } + } + else + { + // they much be one of the DECODING*_EXC + if (respException != null) + { + errString = respException.getMessage(); + } + else + { + errString = "Decoding Exception"; + } + } + } + return errString; +} + +/** + * Returns whether or not this PDU is timed out, i.e. it did not get + * a response. + * Its errorStatus will be set to AsnObject.SNMP_ERR_GENERR. + * + *

    + * Note that a SNMP agent can respond with an errorStatus of + * AsnObject.SNMP_ERR_GENERR as well, so getting a + * AsnObject.SNMP_ERR_GENERR does not necessarily mean that the request + * is timed out! + *

    + * + * @return true is the PDU was timed out + * @see #getErrorStatus + * @see SnmpConstants#SNMP_ERR_GENERR + */ +public boolean isTimedOut() +{ + return isTimedOut; +} + + +/** + * This method will wait until the answer is received, instead of + * continue with other stuff. + */ +public boolean waitForSelf() +{ + // Add an extra second to the waiting. This gives the PDU a chance + // to handle the timeout correctly before this thread wakes up. + long del = 1000; + for (int i=0; i< retry_intervals.length; i++) + { + del += retry_intervals[i]; + } + boolean res = waitForSelf(del); + + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".waitForSelf(): reqId=" + req_id + " " + res); + } + + // Should I?? + if (!answered) + { + handleNoAnswer(); + } + + return res; +} + +/** + * Returns the string representation of the PDU. + * + * @return The string of the PDU + */ +public String toString() +{ + return toString(false); +} + +/** + * Returns the string representation of the PDU with or without the + * response varbinds. + * + * @param withRespVars Include the response varbinds or not + * @return The string of the PDU + */ +protected String toString(boolean withRespVars) +{ + StringBuffer buffer = new StringBuffer(getClass().getName()); + buffer.append("["); + buffer.append("context=").append(context); + buffer.append(", reqId=").append(req_id); + buffer.append(", msgType=0x").append(SnmpUtilities.toHex(msg_type)); + + buffer.append(", "); + buffer.append(printVars("reqVarbinds", reqVarbinds)); + + if (withRespVars == true) + { + buffer.append(", "); + buffer.append(printVars("respVarbinds", respVarbinds)); + } + + buffer.append("]"); + return buffer.toString(); +} + +/** + * Returns the string representation of the varbinds of the PDU. + * + * @see #toString(boolean) + * @since 4_14 + */ +protected StringBuffer printVars(String title, Vector vars) +{ + StringBuffer buffer = new StringBuffer(); + buffer.append(title).append("="); + if (vars != null) + { + int sz = vars.size(); + buffer.append("["); + for (int i=0; i 0) + { + buffer.append(", "); + } + varbind var = (varbind) vars.elementAt(i); + buffer.append(var.toString()); + } + buffer.append("]"); + } + else + { + buffer.append("null"); + } + return buffer; +} + +synchronized boolean waitForSelf(long delay) +{ + if (!got) + { + try + { + wait(delay); + } + catch (InterruptedException ix) + { + ; + } + } + return answered; +} + +void transmit() +{ + transmit(true); +} + +void transmit(boolean withRetries) +{ + if (withRetries == true) + { + int n=0; + answered=false; + + while ((!context.isDestroyed()) && (!answered) && (n 6) + { + System.out.println(getClass().getName() + ".transmit(): Failed to remove reqId " + req_id); + } + } +} + +void setTrans(Transmitter t) +{ + trans = t; +} + + +/** + * Returns the message type, this will indicate what kind of request we + * are dealing with. + * By default it will be set to the GET_REQ_MSG + * + * @return The message type + */ +public byte getMsgType() +{ + return msg_type; +} + +/** + * Sets the message type, this will indicate what kind of request we + * are dealing with. + * By default it will be set to the GET_REQ_MSG + * + * @param type The message type + */ +protected void setMsgType(byte type) +{ + msg_type = type; +} + +/** + * Sets the error status, indicating what went wrong. + * + * @param err the error status + * @see #getErrorIndex + * @see #getErrorStatusString + * @see #getErrorStatus + */ +protected void setErrorStatus(int err) +{ + errstat = err; + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".setErrorStatus(): reqId=" + req_id + " " + errstat); + } + if (errstat != AsnObject.SNMP_ERR_NOERROR) + { + setResponseException(new AgentException(getErrorStatusString())); + } +} + +/** + * Sets the error status and the exception, indicating what went wrong. + * + * @param err the error status + * @param exc the PDU Exception that was thrown whilst decoding + * + * @see #getErrorIndex + * @see #getErrorStatusString + * @see #getErrorStatus + */ +protected void setErrorStatus(int err, PduException exc) +{ + errstat = err; + setResponseException(exc); +} + +/** + * Sets the error index, this indicates which of the OIDs went wrong. + * @param ind the error index + * @see #setErrorStatus(int) + * @see #getErrorIndex + */ +protected void setErrorIndex(int ind) +{ + errind = ind; +} + +/** + * Returns whether or not this type of PDU is expecting some kind of response. + * This method is used in AbstractSnmpContext to help determine whether + * or not to start a thread that listens for a response when sending this + * PDU. + * The default is true. + * + * @return true if a response is expected, false if not. + * @since 4_14 + */ +protected boolean isExpectingResponse() +{ + return true; +} + +/** + * This method is called when no answer is received after all + * retries. + * The application is notified of this. + * See also fillin() + */ +private void handleNoAnswer() +{ + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".handleNoAnswer(): reqId=" + req_id); + } + + // it's a lie, but it will prevent this method from + // being called twice + answered=true; + + isTimedOut = true; + setErrorStatus(AsnObject.SNMP_ERR_GENERR); + setErrorIndex(0); + + setChanged(); + tell_them(); + clearChanged(); + + synchronized(this) + { + notify(); + } +} + +/** + * Fill in the received response. + * @see Pdu#getResponseVarbinds() + * + */ +void fillin(AsnPduSequence seq) +{ + if (answered) + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".fillin(): Got a second answer to reqId " + req_id); + } + return; + } + + // fillin(null) can be called in case of a Decoding exception + if (seq != null) + { + if (seq.isCorrect == true) + { + int n=-1; + try + { + // Fill in the request id + this.req_id = seq.getReqId(); + setErrorStatus(seq.getWhatError()); + setErrorIndex(seq.getWhereError()); + + // The varbinds from the response/report are set in a + // new Vector. + AsnSequence varBind = seq.getVarBind(); + int size = varBind.getObjCount(); + respVarbinds = new Vector(size, 1); + for (n=0; n + * In the case of an exception, the error status + * will be set to one of the decoding errors (see + * getErrorStatus) + * and passed as the parameter + * arg in the + * update(Observable obs, Object arg) + * method. + *

    + * + * @param arg The argument passed to update, can be a PduException. + * @see SnmpConstants#SNMP_ERR_DECODING_EXC + * @see #getErrorStatus + * @see #getResponseVarbinds + * @since 4.5 + */ +public void notifyObservers(Object arg) +{ + if (respException != null) + { + super.notifyObservers(respException); + } + else + { + super.notifyObservers(arg); + } +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/PduException.java b/src/main/java/uk/co/westhawk/snmp/stack/PduException.java new file mode 100644 index 0000000..87e955f --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/PduException.java @@ -0,0 +1,82 @@ +// NAME +// $RCSfile: PduException.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.5 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * @author Birgit Arkesteijn + * @version $Revision: 3.5 $ $Date: 2006/01/17 17:43:54 $ + */ +public class PduException extends Exception +{ + private static final String version_id = + "@(#)$Id: PduException.java,v 3.5 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructs a PduException with no specified detail message. + * + */ +public PduException() +{ + super(); +} + +/** + * Constructs a PduException with the specified detail + * message. + * + * @param str The detail message. + */ +public PduException(String str) +{ + super(str); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/ReportPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/ReportPdu.java new file mode 100644 index 0000000..be0edc1 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/ReportPdu.java @@ -0,0 +1,172 @@ +// NAME +// $RCSfile: ReportPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.3 $ +// CREATED +// $Date: 2006/01/17 17:59:34 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the ASN SNMP Report PDU object. + * This class is used when requests are received that try to discover our + * SNMPv3 timeliness. This will only be the case then the stack acts as + * authoritative engine. + * + *

    + * Reports are not used (as far as we know) in normal + * manager - agent (authoritative - non authoritative) communication. + * Hence the reason why this stack does not support them in any other + * way. + *

    + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.3 $ $Date: 2006/01/17 17:59:34 $ + */ +public class ReportPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: ReportPdu.java,v 3.3 2006/01/17 17:59:34 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructor. + * The requestPdu is used to copy the necessary IDs to this PDU. + * + * @param con The context of the PDU + * @param requestPdu The original Request PDU + */ +public ReportPdu(SnmpContextBasisFace con, Pdu requestPdu) +{ + super(con); + setMsgType(AsnObject.GET_RPRT_MSG); + req_id = requestPdu.req_id; + snmpv3MsgId = requestPdu.snmpv3MsgId; +} + + +/** + * Sets the error status of this PDU. This indicates that an exception + * has occurred while processing the original request. + * + * @see SnmpConstants#SNMP_ERR_NOERROR + * @see SnmpConstants#SNMP_ERR_TOOBIG + * @see SnmpConstants#SNMP_ERR_NOSUCHNAME + * @see SnmpConstants#SNMP_ERR_BADVALUE + * @see SnmpConstants#SNMP_ERR_READONLY + * @see SnmpConstants#SNMP_ERR_GENERR + * @see SnmpConstants#SNMP_ERR_NOACCESS + * @see SnmpConstants#SNMP_ERR_WRONGTYPE + * @see SnmpConstants#SNMP_ERR_WRONGLENGTH + * @see SnmpConstants#SNMP_ERR_WRONGENCODING + * @see SnmpConstants#SNMP_ERR_WRONGVALUE + * @see SnmpConstants#SNMP_ERR_NOCREATION + * @see SnmpConstants#SNMP_ERR_INCONSISTENTVALUE + * @see SnmpConstants#SNMP_ERR_RESOURCEUNAVAILABLE + * @see SnmpConstants#SNMP_ERR_COMMITFAILED + * @see SnmpConstants#SNMP_ERR_UNDOFAILED + * @see SnmpConstants#SNMP_ERR_AUTHORIZATIONERR + * @see SnmpConstants#SNMP_ERR_NOTWRITABLE + * @see SnmpConstants#SNMP_ERR_INCONSISTENTNAME + */ +public void getErrorStatus(int errorStatus) +{ + errstat = errorStatus; +} + + +/** + * Sets the error index of this PDU. When the error status is not + * SNMP_ERR_NOERROR, it indicates the index of the variable in the + * varbind list that caused the exception. + */ +public void getErrorIndex(int errorIndex) +{ + errind = errorIndex; +} + +/** + * The Report PDU does not get a response back. So it should be sent once. + */ +void transmit() +{ + transmit(false); +} + +/** + * Returns the string representation of this object. + * + * @return The string of the PDU + */ +public String toString() +{ + return super.toString(true); +} + +/** + * Has no meaning, since there is not response. + */ +protected void new_value(int n, varbind res){} + +/** + * Has no meaning, since there is not response. + */ +protected void tell_them(){} + +/** + * Returns that this type of PDU is not expecting a response. + * This method is used in AbstractSnmpContext to help determine whether + * or not to start a thread that listens for a response when sending this + * PDU. + * The default is false. + * + * @return true if a response is expected, false if not. + */ +protected boolean isExpectingResponse() +{ + return false; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/ResponsePdu.java b/src/main/java/uk/co/westhawk/snmp/stack/ResponsePdu.java new file mode 100644 index 0000000..2289f3b --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/ResponsePdu.java @@ -0,0 +1,183 @@ +// NAME +// $RCSfile: ResponsePdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.6 $ +// CREATED +// $Date: 2006/11/30 14:45:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the ASN SNMP Response PDU object. + * This class should be used when responding to an incoming request + * via a ListeningContext. Note that you should use the port of the + * RequestPduEvent (getHostPort()) when creating a SnmpContext. + * + *

    + * This class is not used when request are sent out by the + * stack and a response is received. In that case the OIDs of the + * response are integrated into the original request PDU. + *

    + * + *

    + * For SNMPv3: The sender of a response PDU acts as the authoritative engine. + *

    + * + * @see ListeningContext + * @see uk.co.westhawk.snmp.event.RequestPduEvent + * @see uk.co.westhawk.snmp.event.RequestPduEvent#getHostPort() + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.6 $ $Date: 2006/11/30 14:45:50 $ + */ +public class ResponsePdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: ResponsePdu.java,v 3.6 2006/11/30 14:45:50 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructor. + * The requestPdu is used to copy the necessary IDs to this PDU. + * + * @param con The context of the PDU + * @param requestPdu The original Request PDU + */ +public ResponsePdu(SnmpContextBasisFace con, Pdu requestPdu) +{ + super(con); + setMsgType(AsnObject.GET_RSP_MSG); + req_id = requestPdu.req_id; + snmpv3MsgId = requestPdu.snmpv3MsgId; +} + + +/** + * Sets the error status of this PDU. This indicates that an exception + * has occurred while processing the original request. + * + * @see SnmpConstants#SNMP_ERR_NOERROR + * @see SnmpConstants#SNMP_ERR_TOOBIG + * @see SnmpConstants#SNMP_ERR_NOSUCHNAME + * @see SnmpConstants#SNMP_ERR_BADVALUE + * @see SnmpConstants#SNMP_ERR_READONLY + * @see SnmpConstants#SNMP_ERR_GENERR + * @see SnmpConstants#SNMP_ERR_NOACCESS + * @see SnmpConstants#SNMP_ERR_WRONGTYPE + * @see SnmpConstants#SNMP_ERR_WRONGLENGTH + * @see SnmpConstants#SNMP_ERR_WRONGENCODING + * @see SnmpConstants#SNMP_ERR_WRONGVALUE + * @see SnmpConstants#SNMP_ERR_NOCREATION + * @see SnmpConstants#SNMP_ERR_INCONSISTENTVALUE + * @see SnmpConstants#SNMP_ERR_RESOURCEUNAVAILABLE + * @see SnmpConstants#SNMP_ERR_COMMITFAILED + * @see SnmpConstants#SNMP_ERR_UNDOFAILED + * @see SnmpConstants#SNMP_ERR_AUTHORIZATIONERR + * @see SnmpConstants#SNMP_ERR_NOTWRITABLE + * @see SnmpConstants#SNMP_ERR_INCONSISTENTNAME + * + * @since 5_2 + */ +public void setErrorStatus(int errorStatus) +{ + errstat = errorStatus; +} + + +/** + * Sets the error index of this PDU. When the error status is not + * SNMP_ERR_NOERROR, it indicates the index of the variable in the + * varbind list that caused the exception. + * + * @since 5_2 + */ +public void setErrorIndex(int errorIndex) +{ + errind = errorIndex; +} + +/** + * The Response PDU does not get a response back. So it should be sent once. + */ +void transmit() +{ + transmit(false); +} + +/** + * Returns the string representation of this object. + * + * @return The string of the PDU + */ +public String toString() +{ + return super.toString(true); +} + +/** + * Has no meaning, since there is not response. + */ +protected void new_value(int n, varbind res){} + +/** + * Has no meaning, since there is not response. + */ +protected void tell_them(){} + +/** + * Returns that this type of PDU is not expecting a response. + * This method is used in AbstractSnmpContext to help determine whether + * or not to start a thread that listens for a response when sending this + * PDU. + * The default is false. + * + * @return true if a response is expected, false if not. + */ +protected boolean isExpectingResponse() +{ + return false; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SetPdu.java b/src/main/java/uk/co/westhawk/snmp/stack/SetPdu.java new file mode 100644 index 0000000..27c0aad --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SetPdu.java @@ -0,0 +1,92 @@ +// NAME +// $RCSfile: SetPdu.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the SNMP Set Pdu. + * + * @see #addOid(String, AsnObject) + * @see #addOid(AsnObjectId, AsnObject) + * + * @author Birgit Arkesteijn + * @version $Revision: 3.9 $ $Date: 2006/01/17 17:43:54 $ + */ +public class SetPdu extends Pdu +{ + private static final String version_id = + "@(#)$Id: SetPdu.java,v 3.9 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * Constructor. + * + * @param con The context of the Pdu + */ + public SetPdu(SnmpContextBasisFace con) + { + super(con); + setMsgType(AsnObject.SET_REQ_MSG); + } + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpConstants.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpConstants.java new file mode 100644 index 0000000..565c75d --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpConstants.java @@ -0,0 +1,376 @@ +// NAME +// $RCSfile: SnmpConstants.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2006/03/23 14:54:10 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/** + * This interface contains most of the constants used in the stack. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.10 $ $Date: 2006/03/23 14:54:10 $ + */ +public interface SnmpConstants +{ + static final String version_id = + "@(#)$Id: SnmpConstants.java,v 3.10 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + +public static final byte ASN_BOOLEAN =(byte)(0x01); +public static final byte ASN_INTEGER =(byte)(0x02); +public static final byte ASN_BIT_STR =(byte)(0x03); +public static final byte ASN_OCTET_STR =(byte)(0x04); +public static final byte ASN_NULL =(byte)(0x05); +public static final byte ASN_OBJECT_ID =(byte)(0x06); +public static final byte ASN_SEQUENCE =(byte)(0x10); +public static final byte ASN_SET =(byte)(0x11); + +public static final byte ASN_UNIVERSAL =(byte)(0x00); +public static final byte ASN_APPLICATION =(byte)(0x40); +public static final byte ASN_CONTEXT =(byte)(0x80); +public static final byte ASN_PRIVATE =(byte)(0xC0); + +public static final byte ASN_PRIMITIVE =(byte)(0x00); +public static final byte ASN_CONSTRUCTOR =(byte)(0x20); + +public static final byte ASN_LONG_LEN =(byte)(0x80); +public static final byte ASN_EXTENSION_ID=(byte)(0x1F); +public static final byte ASN_BIT8 =(byte)(0x80); + +public static final byte INTEGER =(byte)ASN_INTEGER; +public static final byte STRING =(byte)ASN_OCTET_STR; +public static final byte OBJID =(byte)ASN_OBJECT_ID; +public static final byte NULLOBJ =(byte)ASN_NULL; + +/** IPv4 address only */ +// RFC 2578: +public static final byte IPADDRESS =(byte)(ASN_APPLICATION | 0); +public static final byte COUNTER =(byte)(ASN_APPLICATION | 1); +public static final byte GAUGE =(byte)(ASN_APPLICATION | 2); +public static final byte TIMETICKS =(byte)(ASN_APPLICATION | 3); +public static final byte OPAQUE =(byte)(ASN_APPLICATION | 4); +public static final byte COUNTER64 =(byte)(ASN_APPLICATION | 6); + +/** + * for OSI NSAP addresses (see + * RFC 1442, + * is obsoleted by + * RFC 2578). + */ +public static final byte NSAP_ADDRESS =(byte)(ASN_APPLICATION | 5); + +/** + * an unsigned 32-bit quantity (see + * RFC 1902, + * is obsoleted by + * SNMPv2-SMI). + * + *

    + * Was called UINTEGER32. Renamed it in version 4_13. + *

    + */ +public static final byte OBSOLETED_RFC1442_UINTEGER32 =(byte)(ASN_APPLICATION | 7); + +/** + * an unsigned 32-bit quantity. This equals GAUGE. (see + * SNMPv2-SMI). + */ +public static final byte SMI_V2_UINTEGER32 = GAUGE; + +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_COLDSTART =(byte)(0x0); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_WARMSTART =(byte)(0x1); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_LINKDOWN =(byte)(0x2); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_LINKUP =(byte)(0x3); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_AUTHFAIL =(byte)(0x4); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_EGPNEIGHBORLOSS =(byte)(0x5); +/** + * Value for the GenericTrap field in SNMPv1 Trap. + */ +public static final byte SNMP_TRAP_ENTERPRISESPECIFIC=(byte)(0x6); + +/** + * Indicated the agent does not implement the object referred to by + * this object identifier. + * Used in varbind list in response to SNMPv2c, SNMPv3 getRequest. + */ +public static final byte SNMP_VAR_NOSUCHOBJECT =(byte)(ASN_CONTEXT | ASN_PRIMITIVE | 0x0); +/** + * Indicated that this object does not exists for this operation. + * Used in varbind list in response to SNMPv2c, SNMPv3 getRequest. + */ +public static final byte SNMP_VAR_NOSUCHINSTANCE =(byte)(ASN_CONTEXT | ASN_PRIMITIVE | 0x1); +/** + * Indicated an attempt to reference an object identifier that is + * beyond the end of the MIB at the agent. + * Used in varbind list in response to SNMPv2c, SNMPv3 getRequest or getBulkRequest. + */ +public static final byte SNMP_VAR_ENDOFMIBVIEW =(byte)(ASN_CONTEXT | ASN_PRIMITIVE | 0x2); + + +/** + * No error in the PDU response. + * Used in SNMPv1, SNMPv2c, SNMPv3. + */ +public static final byte SNMP_ERR_NOERROR =(byte)(0x00); +/** + * The size of the generated response PDU would exceed a local + * limitation. + * Used in SNMPv1, SNMPv2c, SNMPv3. + */ +public static final byte SNMP_ERR_TOOBIG =(byte)(0x01); +/** + * The object is not available or the object's name does not exactly + * match. + * Only used in SNMPv1. + */ +public static final byte SNMP_ERR_NOSUCHNAME =(byte)(0x02); +/** + * The object does not manifest a type, length, and value + * that is consistent with that required for the variable. + * Only used in response to SNMPv1 SetRequest. + */ +public static final byte SNMP_ERR_BADVALUE =(byte)(0x03); +/** + * The object can not be set, only read. + * Only used in response to SNMPv1 SetRequest. + */ +public static final byte SNMP_ERR_READONLY =(byte)(0x04); +/** + * The value of an object cannot be retrieved for reasons + * not covered by any of other errors. + * Used in SNMPv1, SNMPv2c, SNMPv3. + */ +public static final byte SNMP_ERR_GENERR =(byte)(0x05); + +/** + * The variable binding's name specifies an existing or + * non-existent variable to which this request is/would be denied + * access because it is/would not be in the appropriate MIB view. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_NOACCESS =(byte)(0x06); +/** + * The variable binding's value field specifies a type which is + * inconsistent with that required for all variables which share the + * same OBJECT IDENTIFIER prefix as the variable binding's name. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_WRONGTYPE =(byte)(0x07); +/** + * The variable binding's value field specifies a length which is + * inconsistent with that required for all variables which share the + * same OBJECT IDENTIFIER prefix as the variable binding's name. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_WRONGLENGTH =(byte)(0x08); +/** + * Otherwise, if the variable binding's value field contains an ASN.1 + * encoding which is inconsistent with that field's ASN.1 tag. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_WRONGENCODING =(byte)(0x09); +/** + * The variable binding's value field specifies a value which could + * under no circumstances be assigned to the variable. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_WRONGVALUE =(byte)(0x0A); +/** + * The variable binding's name specifies a variable which does not + * exist and could not ever be created (even though some variables + * sharing the same OBJECT IDENTIFIER prefix might under some + * circumstances be able to be created). + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_NOCREATION =(byte)(0x0B); +/** + * The variable binding's value field specifies a value that could + * under other circumstances be held by the variable, but is presently + * inconsistent or otherwise unable to be assigned to the variable. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_INCONSISTENTVALUE =(byte)(0x0C); +/** + * The assignment of the value specified by the variable binding's + * value field to the specified variable requires the allocation of a + * resource which is presently unavailable. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_RESOURCEUNAVAILABLE =(byte)(0x0D); +/** + * Any of the assignments failed and all other assignments were + * undone. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_COMMITFAILED =(byte)(0x0E); +/** + * Any of the assignments failed and all other assignments were + * undone, but is was not possible to undo all the assignments. + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_UNDOFAILED =(byte)(0x0F); +/** + * Users is has no access privileges. + * Used in SNMPv2c, SNMPv3. + */ +public static final byte SNMP_ERR_AUTHORIZATIONERR =(byte)(0x10); +/** + *
      + *
    • + * There are no variables which share the same OBJECT IDENTIFIER + * prefix as the variable binding's name, and which are able to be + * created or modified no matter what new value is specified. + *
    • + *
    • + * The variable binding's name specifies a variable which exists but + * can not be modified no matter what new value is specified. + *
    • + *
    + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_NOTWRITABLE =(byte)(0x11); +/** + * The variable binding's name specifies a variable which does not + * exist but can not be created under the present circumstances (even + * though it could be created under other circumstances). + * Used in response to SNMPv2c, SNMPv3 SetRequest. + */ +public static final byte SNMP_ERR_INCONSISTENTNAME =(byte)(0x12); + +/** + * A general decoding exception occured whilst decoding the response. + */ +public static final byte SNMP_ERR_DECODING_EXC =(byte)(0x13); +/** + * A specific decoding exception occured whilst decoding the response. + * The response PDU being decoded has a sub length wrong (not overall + * length necessarily), so the asn sequence can't get created. + */ +public static final byte SNMP_ERR_DECODINGASN_EXC =(byte)(0x14); +/** + * A specific decoding exception occured whilst decoding the response. + * The received overall response PDU is shorter than the PDU header + * says it is. + */ +public static final byte SNMP_ERR_DECODINGPKTLNGTH_EXC = (byte)(0x15); + +/** + * The version number for SNMPv1. + */ +public static final byte SNMP_VERSION_1 =(byte)(0x0); +/** + * The version number for SNMPv2c. + */ +public static final byte SNMP_VERSION_2c =(byte)(0x1); +/** + * The version number for SNMPv2u. + */ +//public static final byte SNMP_VERSION_2u =(byte)(0x2); +/** + * The version number for SNMPv3. + */ +public static final byte SNMP_VERSION_3 =(byte)(0x3); + +/** + * The GetRequest PDU type. + */ +static final byte GET_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0); +/** + * The GetNextRequest PDU type. + */ +static final byte GETNEXT_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1); +/** + * The Response PDU type. + */ +static final byte GET_RSP_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2); +/** + * The SetRequest PDU type. + */ +static final byte SET_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3); +/** + * The SNMPv1 Trap PDU type. + */ +static final byte TRP_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4); + +/** + * The GetBulkRequest PDU type. + */ +static final byte GETBULK_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5); +/** + * The InformRequest PDU type. + */ +static final byte INFORM_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6); +/** + * The SNMPv2 (and SNMPv3) Trap PDU type. + */ +static final byte TRPV2_REQ_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7); +/** + * The GetReport PDU type. + */ +static final byte GET_RPRT_MSG =(byte)(ASN_CONTEXT | ASN_CONSTRUCTOR | 0x8); + +static final byte CONS_SEQ =(byte)(ASN_SEQUENCE | ASN_CONSTRUCTOR); + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContext.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContext.java new file mode 100644 index 0000000..3070552 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContext.java @@ -0,0 +1,374 @@ +// NAME +// $RCSfile: SnmpContext.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.25 $ +// CREATED +// $Date: 2009/03/05 12:51:29 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.net.*; +import java.io.*; +import java.util.*; +import uk.co.westhawk.snmp.event.*; + +/** + * This class contains the SNMP v1 context that is needed by every PDU to + * send a SNMP v1 request. + * + *

    + * destroy() should be called when the context is no longer + * used. This is the only way the threads will be stopped and garbage + * collected. + *

    + * + * @see SnmpContextFace + * @see SnmpContextPool + * @author Tim Panton + * @version $Revision: 3.25 $ $Date: 2009/03/05 12:51:29 $ + */ +public class SnmpContext extends AbstractSnmpContext +implements SnmpContextFace, Cloneable +{ + private static final String version_id = + "@(#)$Id: SnmpContext.java,v 3.25 2009/03/05 12:51:29 birgita Exp $ Copyright Westhawk Ltd"; + + String community = SnmpContextFace.DEFAULT_COMMUNITY; + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see AbstractSnmpContext#AbstractSnmpContext(String, int) + */ +public SnmpContext(String host, int port) throws IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The local address the server will bind to + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + */ +public SnmpContext(String host, int port, String typeSocketA) +throws IOException +{ + super(host, port, typeSocketA); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContext(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + super(host, port, bindAddress, typeSocketA); +} + +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_1; +} + +public String getCommunity() +{ + return community; +} + +public void setCommunity(String newCommunity) +{ + community = newCommunity; +} + +public byte[] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws IOException, EncodingException +{ + byte [] packet = null; + if (isDestroyed == true) + { + throw new EncodingException("Context can no longer be used, since it is already destroyed"); + } + else + { + AsnEncoderv1 enc = new AsnEncoderv1(); + ByteArrayOutputStream bay = enc.EncodeSNMP(this, msg_type, rId, errstat, + errind, ve); + + int sz = bay.size(); + if (sz > maxRecvSize) + { + throw new EncodingException("Packet size ("+ sz + + ") is > maximum size (" + maxRecvSize +")"); + } + packet = bay.toByteArray(); + } + return packet; +} + + +public byte[] encodePacket(byte msg_type, String enterprise, + byte[] IpAddress, int generic_trap, int specific_trap, + long timeTicks, Enumeration ve) + throws IOException, EncodingException +{ + byte [] packet = null; + AsnEncoderv1 enc = new AsnEncoderv1(); + ByteArrayOutputStream bay = enc.EncodeSNMP(this, msg_type, enterprise, + IpAddress, generic_trap, specific_trap, timeTicks, ve); + + int sz = bay.size(); + if (sz > maxRecvSize) + { + throw new EncodingException("Packet size ("+ sz + + ") is > maximum size (" + maxRecvSize +")"); + } + packet = bay.toByteArray(); + return packet; +} + +/** + * Processes an incoming SNMP v1 response. + */ +protected void processIncomingResponse(ByteArrayInputStream in) +throws DecodingException, IOException +{ + AsnDecoderv1 rpdu = new AsnDecoderv1(); + AsnSequence seqPdu = rpdu.DecodeSNMP(in, getCommunity()); + if (seqPdu instanceof AsnPduSequence) + { + AsnPduSequence pduSeq = (AsnPduSequence) seqPdu; + if (pduSeq != null) + { + // got a message + Integer rid = new Integer(pduSeq.getReqId()); + Pdu answ = getPdu(rid); + if (answ != null) + { + answ.fillin(pduSeq); + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): No Pdu with reqid " + rid.intValue()); + } + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): Error - missing seq input"); + } + } + } + else + { + // it must be a Trap + } +} + +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, IOException +{ + AsnDecoderv1 rpdu = new AsnDecoderv1(); + ByteArrayInputStream in = new ByteArrayInputStream(message); + + Pdu pdu = null; + AsnSequence seqPdu = rpdu.DecodeSNMP(in, getCommunity()); + if (seqPdu instanceof AsnTrapPduv1Sequence) + { + AsnTrapPduv1Sequence pduSeq = (AsnTrapPduv1Sequence) seqPdu; + if (pduSeq != null) + { + TrapPduv1 trapPdu = new TrapPduv1(this); + trapPdu.fillin(pduSeq); + pdu = trapPdu; + } + } + else + { + // must be an ordinary PDU + AsnPduSequence pduSeq = (AsnPduSequence) seqPdu; + if (pduSeq != null) + { + byte type = pduSeq.getRespType(); + switch (type) + { + case SnmpConstants.GET_REQ_MSG: + pdu = new GetPdu(this); + break; + case SnmpConstants.GETNEXT_REQ_MSG: + pdu = new GetNextPdu(this); + break; + case SnmpConstants.SET_REQ_MSG: + pdu = new SetPdu(this); + break; + //case SnmpConstants.GET_RSP_MSG: + // A longly response should never be received here. + // They should come in via the processIncomingResponse + // route. + //case SnmpConstants.GETBULK_REQ_MSG: + // not in v1 + //case SnmpConstants.INFORM_REQ_MSG: + // not in v1 + //case SnmpConstants.GET_RPRT_MSG: + // not in v1 + //case SnmpConstants.TRPV2_REQ_MSG: + // not in v1 + default: + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".ProcessIncomingPdu(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Ignoring it."); + } + } + + if (pdu != null) + { + pdu.fillin(pduSeq); + } + } + } + return pdu; +} + +/** + * Returns a clone of this SnmpContext. + * + * @exception CloneNotSupportedException Thrown when the constructor + * generates an IOException + */ +public Object clone() throws CloneNotSupportedException +{ + SnmpContext clContext = null; + try + { + clContext = new SnmpContext(hostname, hostPort, bindAddr, typeSocket); + clContext.setCommunity(new String(community)); + } + catch (IOException exc) + { + throw new CloneNotSupportedException("IOException " + + exc.getMessage()); + } + return clContext; +} + + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for a hashtable of (v1) contexts. + * + * @since 4_14 + * @return The hash key + */ +public String getHashKey() +{ + String str = hostname + + "_" + hostPort + + "_" + bindAddr + + "_" + typeSocket + + "_" + community + + "_v" + getVersion(); + return str; +} + +/** + * Returns a string representation of the object. + * + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer("SnmpContext["); + buffer.append("host=").append(hostname); + buffer.append(", port=").append(hostPort); + buffer.append(", bindAddress=").append(bindAddr); + buffer.append(", socketType=").append(typeSocket); + buffer.append(", community=").append(community); + buffer.append(", #trapListeners=").append(trapSupport.getListenerCount()); + buffer.append(", #pduListeners=").append(pduSupport.getListenerCount()); + buffer.append("]"); + return buffer.toString(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextBasisFace.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextBasisFace.java new file mode 100644 index 0000000..a9b45bb --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextBasisFace.java @@ -0,0 +1,495 @@ +// NAME +// $RCSfile: SnmpContextBasisFace.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.9 $ +// CREATED +// $Date: 2006/11/29 16:25:19 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.net.*; + +/** + * This interface contains the SNMP context interface that is needed + * by every PDU to send a SNMP v1, v2c and v3 request. The context also + * provides functionality to receive incoming PDUs. + * + * @see SnmpContext + * @see SnmpContextv2c + * @see SnmpContextv3 + * + * @author Tim Panton + * @version $Revision: 3.9 $ $Date: 2006/11/29 16:25:19 $ + */ +public interface SnmpContextBasisFace +{ + static final String version_id = + "@(#)$Id: SnmpContextBasisFace.java,v 3.9 2006/11/29 16:25:19 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The default port number where SNMP requests are sent to (161). + */ + public final static int DEFAULT_PORT = 161; + /** + * The Standard Socket type. + */ + public final static String STANDARD_SOCKET = "Standard"; + /** + * The TCP Socket type. + */ + public final static String TCP_SOCKET = "TCP"; + + /** + * The Maximum number of outstanding PDUs one context can handle at a + * given moment in time. + */ + final static int MAXPDU = 20; // if you have more than 20 oustanding PDUS + // change the algorythm :-) + /** + * The Maximum size of a message in octets (1300). + */ + final static int MSS = 1300; // maximum recv size; + +/** + * Returns the SNMP version of the context. + * + * @see SnmpConstants#SNMP_VERSION_1 + * @see SnmpConstants#SNMP_VERSION_2c + * @see SnmpConstants#SNMP_VERSION_3 + * + * @return The version + */ +public int getVersion(); + +/** + * Returns the host. + * + * @return The host + */ +public String getHost(); + +/** + * Returns the port number. + * + * @return The port no + */ +public int getPort(); + +/** + * Returns the local bind address. + * If bindAddress is null, then the system will pick up a valid local + * address to bind the socket. + * + * @return The local bind address + * @since 4_14 + */ +public String getBindAddress(); + +/** + * Returns the type of socket. + * + * @see #STANDARD_SOCKET + * @see #TCP_SOCKET + * @return The type of socket + */ +public String getTypeSocket(); + +/** + * Returns the IP address string + * aaa.bbb.ccc.ddd (IPv4) or a:b:c:d:e:f:g:h (IPv6) + * of the host the packets where sent to. + * + * @return The IP address of the host the packets where sent to. + * @see ContextSocketFace#getSendToHostAddress + * @since 4_14 + */ +public String getSendToHostAddress(); + +/** + * Returns the IP address string + * aaa.bbb.ccc.ddd (IPv4) or a:b:c:d:e:f:g:h (IPv6) + * of the (latest) host the packets where received from. + * + * @return The IP address of the (latest) host the packets where received from. + * @see ContextSocketFace#getReceivedFromHostAddress + * @since 4_14 + */ +public String getReceivedFromHostAddress(); + +/** + * Adds a PDU to the context. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the Pdu itself and is added to the interface to + * cover the different kind of Contexts. + * + * @param pdu the PDU + * @return whether the PDU has been successfully added + */ +public boolean addPdu(Pdu pdu) +throws java.io.IOException, PduException; + +/** + * Removes a PDU from the context. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * + * @param requestId the PDU request id + * @return whether the PDU has been successfully removed + */ +public boolean removePdu(int requestId); + +/** + * Encodes a PDU. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * + * @param msg_type The message type + * @param rId The message id + * @param errstat The error status + * @param errind The error index + * @param ve The varbind list + * @param obj Additional object (only used in SNMPv3) + * @return The encoded packet + */ +public byte[] encodePacket(byte msg_type, int rId, int errstat, int errind, + java.util.Enumeration ve, Object obj) + throws java.io.IOException, EncodingException; + +/** + * Sends an encoded PDU. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * + * @param packet The encoded packet + */ +public void sendPacket(byte[] packet); + +/** + * Removes the resouces held by this context. Should be called by the + * user/developer when the context is no longer needed. + */ +public void destroy(); + +/** + * Returns whether or not this context has been destroyed. + * @since 4_14 + */ +public boolean isDestroyed(); + +/** + * Adds the specified trap listener to receive traps on the default trap + * port 162 from the host that matches this context. + * + *

    + * The ListeningContext class will do the actual listening for traps. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a trap pdu. + *

    + * + * @param l The trap listener + * @see #addTrapListener(TrapListener, int) + * @see ListeningContextFace#DEFAULT_TRAP_PORT + */ +public void addTrapListener(TrapListener l) throws java.io.IOException; + +/** + * Removes the specified trap listener from listening for packets on + * the default trap port 162. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeTrapListenerFromPool() + *

    + * + * @param l The trap listener + * @see #removeTrapListener(TrapListener, int) + * @see ListeningContextFace#DEFAULT_TRAP_PORT + */ +public void removeTrapListener(TrapListener l) throws java.io.IOException; + +/** + * Adds the specified trap listener to receive traps on the specified + * port from the host that matches this context. + * + *

    + * The ListeningContext class will do the actual listening for traps. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a trap pdu. + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#addRawPduListener(RawPduListener) + * + * @param l The trap listener + * @param port The port the traps are received on + * @since 4_14 + */ +public void addTrapListener(TrapListener l, int port) throws java.io.IOException; + +/** + * Removes the specified trap listener from listening for packets on the + * specified port. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeTrapListenerFromPool() + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#removeRawPduListener(RawPduListener) + * @see ListeningContextPool#removeRawPduListenerFromPool(RawPduListener) + * + * @param l The trap listener + * @param port The port the traps are received on + * @since 4_14 + */ +public void removeTrapListener(TrapListener l, int port) throws java.io.IOException; + +/** + * Adds the specified trap listener to receive traps on the specified + * listening context that matches this context. + * + *

    + * The ListeningContext class will do the actual listening for traps. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a trap pdu. + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#addRawPduListener(RawPduListener) + * + * @param l The trap listener + * @param lcontext The listening context + * @since 4_14 + */ +public void addTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException; + +/** + * Removes the specified trap listener from listening for packets on the + * specified listening context. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeTrapListenerFromPool() + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#removeRawPduListener(RawPduListener) + * @see ListeningContextPool#removeRawPduListenerFromPool(RawPduListener) + * + * @param l The trap listener + * @param lcontext The listening context + * @since 4_14 + */ +public void removeTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException; + +/** + * Adds the specified request pdu listener to receive PDUs on the + * default request pdu port 161 from the host that matches + * this context. + * + *

    + * The ListeningContext class will do the actual listening for PDUs. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a request pdu. + *

    + * + *

    + * Don't use the TCP_SOCKET when listening for request PDUs. It doesn't + * provide functionality to send a response back. + *

    + * + * @see #addRequestPduListener(RequestPduListener, int) + * @see SnmpContextBasisFace#DEFAULT_PORT + * + * @param l The request PDU listener + * @since 4_14 + */ +public void addRequestPduListener(RequestPduListener l) throws java.io.IOException; + +/** + * Removes the specified request pdu listener from listening for packets + * on the default request pdu port 161. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeRequestPduListenerFromPool() + *

    + * + * @see #removeRequestPduListener(RequestPduListener, int) + * @see SnmpContextBasisFace#DEFAULT_PORT + * + * @param l The request PDU listener + * @since 4_14 + */ +public void removeRequestPduListener(RequestPduListener l) throws java.io.IOException; + +/** + * Adds the specified request pdu listener to receive PDUs on the specified + * port from the host that matches this context. + * + *

    + * The ListeningContext class will do the actual listening for PDUs. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a request pdu. + *

    + * + *

    + * Don't use the TCP_SOCKET when listening for request PDUs. It doesn't + * provide functionality to send a response back. + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#addRawPduListener(RawPduListener) + * + * @param l The request PDU listener + * @param port The port the request PDUs are received on + * @since 4_14 + */ +public void addRequestPduListener(RequestPduListener l, int port) throws java.io.IOException; + +/** + * Removes the specified request pdu listener from listening for packets + * on the specified port. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeRequestPduListenerFromPool() + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#removeRawPduListener(RawPduListener) + * @see ListeningContextPool#removeRawPduListenerFromPool(RawPduListener) + * + * @param l The request PDU listener + * @param port The port the request PDUs are received on + * @since 4_14 + */ +public void removeRequestPduListener(RequestPduListener l, int port) throws java.io.IOException; + +/** + * Adds the specified request pdu listener to receive PDUs on the + * specified listening context that matches this context. + * + *

    + * The ListeningContext class will do the actual listening for PDUs. + * This context will add itself to a ListeningContextPool object and + * will only pass the event to its listeners if the pdu matches this + * context and is a request pdu. + *

    + * + *

    + * Don't use the TCP_SOCKET when listening for request PDUs. It doesn't + * provide functionality to send a response back. + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#addRawPduListener(RawPduListener) + * + * @param l The request PDU listener + * @param lcontext The listening context + * @since 4_14 + */ +public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException; + +/** + * Removes the specified request pdu listener from listening for packets + * on the specified listening context. + * + *

    + * The listener will not be removed from all ListeningContext objects + * that are in the ListeningContextPool. In order to do that, use + * ListeningContextPool.removeRequestPduListenerFromPool() + *

    + * + * @see ListeningContextPool#ListeningContextPool(int, String, String) + * @see ListeningContextPool#removeRawPduListener(RawPduListener) + * @see ListeningContextPool#removeRawPduListenerFromPool(RawPduListener) + * + * @param l The request PDU listener + * @param lcontext The listening context + * @since 4_14 + */ +public void removeRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException; + +/** + * Processes an incoming PDU. The context will try to process the + * incoming PDU, using the SNMP version and other security + * parameters. If any of these do not correspond, a DecodingException + * will be thrown. + */ +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, java.io.IOException; + +/** + * Returns a clone of this SnmpContext. + * + * @since 4_14 + * @exception CloneNotSupportedException Thrown when the constructor + * generates an IOException or when in one of the Pool classes. + */ +public Object clone() throws CloneNotSupportedException; + +/** + * Returns the hash key. This key is built out of all properties. + * + * @since 4_14 + * @return The hash key + */ +public String getHashKey(); +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextFace.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextFace.java new file mode 100644 index 0000000..6a9de3b --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextFace.java @@ -0,0 +1,90 @@ +// NAME +// $RCSfile: SnmpContextFace.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.13 $ +// CREATED +// $Date: 2006/02/09 14:19:05 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.event.*; + +/** + * This interface contains the (basic) SNMP context interface that is needed + * by every PDU to send a SNMP v1 request. The context also + * provides functionality to receive incoming PDUs. + * + * @see SnmpContext + * @see SnmpContextv2c + * @see SnmpContextv3 + * + * @author Tim Panton + * @version $Revision: 3.13 $ $Date: 2006/02/09 14:19:05 $ + */ +public interface SnmpContextFace extends SnmpContextBasisFace +{ + static final String version_id = + "@(#)$Id: SnmpContextFace.java,v 3.13 2006/02/09 14:19:05 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The default community name. This is public. + */ + public final static String DEFAULT_COMMUNITY = "public"; + +/** + * Returns the community name. + */ +public String getCommunity(); + + +/** + * Sets the community name. + * This community name will be used for all PDUs sent with this context. + * The default community name is public. + * + * @see #DEFAULT_COMMUNITY + */ +public void setCommunity(String newCommunity); + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPool.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPool.java new file mode 100644 index 0000000..c821f57 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPool.java @@ -0,0 +1,611 @@ +// NAME +// $RCSfile: SnmpContextPool.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.22 $ +// CREATED +// $Date: 2009/03/05 13:27:41 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.event.*; + +/** + * This class contains the pool of SNMP v1 contexts. + * This class reuses the existings contexts instead of creating a new + * one every time. + *

    + * Every time a property changes the pool is checked for a SnmpContext + * context that matches all the new properties of this class. If no such + * context exists, a new one is made. + * The PDUs associated with the old context remain associated with the + * old context. + *

    + * + *

    + * A counter indicates the number of times the context is referenced. + * The counter is decreased when destroy() is called. + * When the counter reaches zero, the context is released. + *

    + * + *

    + * Note that because the underlying context can change when a property + * is changed and the PDUs remain associated with the old context, all + * properties have to be set BEFORE a PDU is sent. + *

    + * + *

    + * Thanks to Seon Lee (slee@virtc.com) for reporting thread safety + * problems. + *

    + * + * @see SnmpContext + * @see SnmpContextv2cPool + * @see SnmpContextv3Pool + * + * @author Birgit Arkesteijn + * @version $Revision: 3.22 $ $Date: 2009/03/05 13:27:41 $ + */ +public class SnmpContextPool implements SnmpContextFace +{ + private static final String version_id = + "@(#)$Id: SnmpContextPool.java,v 3.22 2009/03/05 13:27:41 birgita Exp $ Copyright Westhawk Ltd"; + + protected static Hashtable contextPool; + + protected SnmpContext context = null; + protected String hostname, socketType, bindAddr; + protected int hostPort; + protected String community = SnmpContextFace.DEFAULT_COMMUNITY; + +/** + * Constructor, using the Standard socket. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see SnmpContext#SnmpContext(String, int) + */ +public SnmpContextPool(String host, int port) throws java.io.IOException +{ + this(host, port, SnmpContextFace.DEFAULT_COMMUNITY, null, STANDARD_SOCKET); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param typeSocket The type of socket to use. + * + * @see SnmpContext#SnmpContext(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public SnmpContextPool(String host, int port, String typeSocket) +throws java.io.IOException +{ + this(host, port, SnmpContextFace.DEFAULT_COMMUNITY, null, typeSocket); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @since 4_12 + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param comm The community name. + * @param typeSocket The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public SnmpContextPool(String host, int port, String comm, String typeSocket) +throws java.io.IOException +{ + this(host, port, comm, null, typeSocket); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param comm The community name. + * @param bindAddress The local address the server will bind to + * @param typeSocket The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContextPool(String host, int port, String comm, String bindAddress, String typeSocket) +throws java.io.IOException +{ + initPools(); + hostname = host; + hostPort = port; + community = comm; + bindAddr = bindAddress; + socketType = typeSocket; + + context = getMatchingContext(); +} + +private static synchronized void initPools() +{ + if (contextPool == null) + { + contextPool = new Hashtable(5); + } +} + +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_1; +} + +public String getHost() +{ + return hostname; +} + +public int getPort() +{ + return hostPort; +} + +public String getBindAddress() +{ + return bindAddr; +} + +public String getTypeSocket() +{ + return socketType; +} + +public String getSendToHostAddress() +{ + String res = null; + if (context != null) + { + res = context.getSendToHostAddress(); + } + return res; +} + +public String getReceivedFromHostAddress() +{ + String res = null; + if (context != null) + { + res = context.getReceivedFromHostAddress(); + } + return res; +} + + +public String getCommunity() +{ + return community; +} + +public void setCommunity(String newCommunity) +{ + if (newCommunity != null + && + newCommunity.equals(community) == false) + + { + community = newCommunity; + try + { + context = getMatchingContext(); + } + catch (java.io.IOException exc) { } + } +} + +public boolean addPdu(Pdu pdu) +throws java.io.IOException, PduException +{ + if (context == null) + { + context = getMatchingContext(); + } + return context.addPdu(pdu); +} + +public boolean removePdu(int requestId) +{ + boolean res = false; + if (context != null) + { + res = context.removePdu(requestId); + } + return res; +} + +/** + * Encodes a PDU packet. + */ +public byte[] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws java.io.IOException, EncodingException +{ + byte[] res = null; + if (context != null) + { + res = context.encodePacket(msg_type, rId, errstat, errind, ve, + obj); + } + return res; +} + +public void sendPacket(byte[] packet) +{ + if (context != null) + { + context.sendPacket(packet); + } +} + +/** + * Releases the resources held by this context. This method will + * decrement the reference counter. When the reference counter reaches + * zero the actual context is removed from the pool and destroyed. + */ +public void destroy() +{ + synchronized(contextPool) + { + if (context != null) + { + String hashKey = context.getHashKey(); + + int count = 0; + SnmpContextPoolItem item = (SnmpContextPoolItem) contextPool.get(hashKey); + if (item != null) + { + count = item.getCounter(); + count--; + item.setCounter(count); + } + + if (count <= 0) + { + contextPool.remove(hashKey); + context.destroy(); + } + context = null; + } + } +} + + +/** + * Destroys all the contexts (v1 and v2c) in the pool and empties the pool. + * The underlying implementation uses the same hashtable for both the v1 + * and the v2c contexts. + * + * @see #destroy() + * @since 4_14 + */ +public void destroyPool() +{ + Hashtable copyOfPool = null; + + synchronized(contextPool) + { + synchronized(contextPool) + { + copyOfPool = (Hashtable) contextPool.clone(); + } + contextPool.clear(); + } + context = null; + + Enumeration keys = copyOfPool.keys(); + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + SnmpContextPoolItem item = (SnmpContextPoolItem) copyOfPool.get(key); + if (item != null) + { + SnmpContextBasisFace cntxt = (SnmpContextBasisFace) item.getContext(); + cntxt.destroy(); + } + } + copyOfPool.clear(); +} + + +public boolean isDestroyed() +{ + boolean isDestroyed = true; + if (context != null) + { + isDestroyed = context.isDestroyed(); + } + return isDestroyed; +} + + +/** + * Returns a context from the pool. + * The pre-existing context (if there is any) is destroyed. + * This methods checks for an existing context that matches all our + * properties. If such a context does not exist, a new one is created and + * added to the pool. + * + * @return A context from the pool + * @see #getHashKey + */ +protected SnmpContext getMatchingContext() throws java.io.IOException +{ + SnmpContextPoolItem item = null; + SnmpContext newContext = null; + String hashKey = getHashKey(); + + destroy(); + synchronized(contextPool) + { + int count=0; + if (contextPool.containsKey(hashKey)) + { + item = (SnmpContextPoolItem) contextPool.get(hashKey); + newContext = (SnmpContext) item.getContext(); + count = item.getCounter(); + } + else + { + newContext = new SnmpContext(hostname, hostPort, bindAddr, socketType); + newContext.setCommunity(community); + item = new SnmpContextPoolItem(newContext); + contextPool.put(hashKey, item); + } + count++; + item.setCounter(count); + } + return newContext; +} + +/** + * Dumps the pool of contexts. This is for debug purposes. + * @param title The title of the dump + */ +public void dumpContexts(String title) +{ + System.out.println(title + " " + contextPool.size() + " context(s)"); + Enumeration keys = contextPool.keys(); + int i=0; + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + SnmpContextPoolItem item = (SnmpContextPoolItem) contextPool.get(key); + if (item != null) + { + int count = item.getCounter(); + SnmpContext cntxt = (SnmpContext) item.getContext(); + + if (cntxt == context) + { + System.out.println("\tcurrent context: "); + } + System.out.println("\tcontext " + i + ": " + key + ", count: " + count + + ", " + cntxt.toString() + "\n" + + ", " + cntxt.getDebugString()); + i++; + } + } +} + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for the hashtable of (v1) contexts. + * + * @return The hash key + */ +public String getHashKey() +{ + String str = hostname + + "_" + hostPort + + "_" + bindAddr + + "_" + socketType + + "_" + community + + "_v" + getVersion(); + return str; +} + +/** + * Adds the specified trap listener. The listener will be added to the + * current context, not to all the contexts in the hashtable. + * + * @see SnmpContext#addTrapListener + */ +public void addTrapListener(TrapListener l) throws java.io.IOException +{ + if (context != null) + { + context.addTrapListener(l); + } +} + +/** + * Removes the specified trap listener. The listener will be removed + * from the current context, not from all the contexts in the + * hashtable. + * + * @see SnmpContext#removeTrapListener + */ +public void removeTrapListener(TrapListener l) throws java.io.IOException +{ + if (context != null) + { + context.removeTrapListener(l); + } +} + +public void addTrapListener(TrapListener l, int port) throws java.io.IOException +{ + if (context != null) + { + context.addTrapListener(l, port); + } +} +public void removeTrapListener(TrapListener l, int port) throws java.io.IOException +{ + if (context != null) + { + context.removeTrapListener(l, port); + } +} + +public void addTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (context != null) + { + context.addTrapListener(l, lcontext); + } +} +public void removeTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (context != null) + { + context.removeTrapListener(l, lcontext); + } +} + +public void addRequestPduListener(RequestPduListener l) throws java.io.IOException +{ + if (context != null) + { + context.addRequestPduListener(l); + } +} +public void removeRequestPduListener(RequestPduListener l) throws java.io.IOException +{ + if (context != null) + { + context.removeRequestPduListener(l); + } +} +public void addRequestPduListener(RequestPduListener l, int port) throws java.io.IOException +{ + if (context != null) + { + context.addRequestPduListener(l, port); + } +} +public void removeRequestPduListener(RequestPduListener l, int port) throws java.io.IOException +{ + if (context != null) + { + context.removeRequestPduListener(l, port); + } +} +public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (context != null) + { + context.addRequestPduListener(l, lcontext); + } +} +public void removeRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (context != null) + { + context.removeRequestPduListener(l, lcontext); + } +} + +/** + * Processes the incoming PDU with the current context. + * + * @see SnmpContext#processIncomingPdu + */ +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, java.io.IOException +{ + Pdu pdu = null; + if (context != null) + { + pdu = context.processIncomingPdu(message); + } + return pdu; +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + String res = ""; + if (context != null) + { + res = context.toString(); + } + return res; +} + +/** + * This method is not supported. It will throw a CloneNotSupportedException. + * + * @since 4_14 + */ +public Object clone() throws CloneNotSupportedException +{ + throw new CloneNotSupportedException(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPoolItem.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPoolItem.java new file mode 100644 index 0000000..8e778aa --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextPoolItem.java @@ -0,0 +1,119 @@ +// NAME +// $RCSfile: SnmpContextPoolItem.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.4 $ +// CREATED +// $Date: 2006/01/17 17:33:04 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2002 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; +import uk.co.westhawk.snmp.event.*; + +/** + * This class contains one context and one reference counter. + * The reference counter + * maintains how many objects reference this context. + * It is a helper class for the context pools, to improve the + * synchronisation. + * + * @see SnmpContextPool + * @see SnmpContextv2cPool + * @see SnmpContextv3Pool + * @since 4_12 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.4 $ $Date: 2006/01/17 17:33:04 $ + */ +class SnmpContextPoolItem +{ + private static final String version_id = + "@(#)$Id: SnmpContextPoolItem.java,v 3.4 2006/01/17 17:33:04 birgit Exp $ Copyright Westhawk Ltd"; + + private SnmpContextBasisFace context = null; + private int counter = 0; + +/** + * Constructor. + * + * @param con The context + */ +SnmpContextPoolItem(SnmpContextBasisFace con) +{ + context = con; + counter = 0; +} + + +SnmpContextBasisFace getContext() +{ + return context; +} + +int getCounter() +{ + return counter; +} + +void setCounter(int i) +{ + counter = i; +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer("SnmpContextPoolItem["); + buffer.append("context=").append(context.toString()); + buffer.append(", counter=").append(counter); + buffer.append("]"); + return buffer.toString(); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2c.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2c.java new file mode 100644 index 0000000..b8a4eec --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2c.java @@ -0,0 +1,303 @@ +// NAME +// $RCSfile: SnmpContextv2c.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.16 $ +// CREATED +// $Date: 2009/03/05 12:54:04 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.net.*; +import java.io.*; +import java.util.*; +import uk.co.westhawk.snmp.event.*; + +/** + * This class contains the SNMP v2c context that is needed by every PDU to + * send a SNMP v2c request. + * + *

    + * destroy() should be called when the context is no longer + * used. This is the only way the threads will be stopped and garbage + * collected. + *

    + * + * @see SnmpContextv2cFace + * @see SnmpContextv2cPool + * @author Birgit Arkesteijn + * @version $Revision: 3.16 $ $Date: 2009/03/05 12:54:04 $ + */ +public class SnmpContextv2c extends SnmpContext +implements SnmpContextv2cFace, Cloneable +{ + private static final String version_id = + "@(#)$Id: SnmpContextv2c.java,v 3.16 2009/03/05 12:54:04 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see AbstractSnmpContext#AbstractSnmpContext(String, int) + */ +public SnmpContextv2c(String host, int port) throws IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The local address the server will bind to + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + */ +public SnmpContextv2c(String host, int port, String typeSocketA) +throws IOException +{ + super(host, port, typeSocketA); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContextv2c(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + super(host, port, bindAddress, typeSocketA); +} + +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_2c; +} + + +public byte[] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws IOException, EncodingException +{ + byte [] packet = null; + if (isDestroyed == true) + { + throw new EncodingException("Context can no longer be used, since it is already destroyed"); + } + else + { + AsnEncoderv2c enc = new AsnEncoderv2c(); + ByteArrayOutputStream bay = enc.EncodeSNMPv2c(this, msg_type, rId, errstat, + errind, ve); + + int sz = bay.size(); + if (sz > maxRecvSize) + { + throw new EncodingException("Packet size ("+ sz + + ") is > maximum size (" + maxRecvSize +")"); + } + packet = bay.toByteArray(); + } + return packet; +} + +/** + * Processes an incoming SNMP v2c response. + */ +protected void processIncomingResponse(ByteArrayInputStream in) +throws DecodingException, IOException +{ + AsnDecoderv2c rpdu = new AsnDecoderv2c(); + AsnPduSequence pduSeq = rpdu.DecodeSNMPv2c(in, getCommunity()); + if (pduSeq != null) + { + // got a message + Integer rid = new Integer(pduSeq.getReqId()); + Pdu answ = getPdu(rid); + if (answ != null) + { + answ.fillin(pduSeq); + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): No Pdu with reqid " + rid.intValue()); + } + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): Error - missing seq input"); + } + } +} + +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, IOException +{ + AsnDecoderv2c rpdu = new AsnDecoderv2c(); + ByteArrayInputStream in = new ByteArrayInputStream(message); + AsnPduSequence pduSeq = rpdu.DecodeSNMPv2c(in, getCommunity()); + + Pdu pdu = null; + if (pduSeq != null) + { + byte type = pduSeq.getRespType(); + switch (type) + { + case SnmpConstants.GET_REQ_MSG: + pdu = new GetPdu(this); + break; + case SnmpConstants.GETNEXT_REQ_MSG: + pdu = new GetNextPdu(this); + break; + case SnmpConstants.SET_REQ_MSG: + pdu = new SetPdu(this); + break; + case SnmpConstants.GETBULK_REQ_MSG: + pdu = new GetBulkPdu(this); + break; + case SnmpConstants.INFORM_REQ_MSG: + pdu = new InformPdu(this); + break; + //case SnmpConstants.GET_RSP_MSG: + // A longly response should never be received here. + // They should come in via the processIncomingResponse + // route. + //case SnmpConstants.GET_RPRT_MSG: + // Reports are part of v3 timeliness communication + case SnmpConstants.TRPV2_REQ_MSG: + pdu = new TrapPduv2(this); + break; + default: + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".ProcessIncomingPdu(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Ignoring it."); + } + } + + if (pdu != null) + { + pdu.fillin(pduSeq); + } + } + return pdu; +} + +/** + * Returns a clone of this SnmpContextv2c. + * + * @exception CloneNotSupportedException Thrown when the constructor + * generates an IOException + */ +public Object clone() throws CloneNotSupportedException +{ + SnmpContextv2c clContext = null; + try + { + clContext = new SnmpContextv2c(hostname, hostPort, bindAddr, typeSocket); + clContext.setCommunity(new String(community)); + } + catch (IOException exc) + { + throw new CloneNotSupportedException("IOException " + + exc.getMessage()); + } + return clContext; +} + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for a hashtable of (v2c) contexts. + * + * @since 4_14 + * @return The hash key + */ +public String getHashKey() +{ + return super.getHashKey(); +} + +/** + * Returns a string representation of the object. + * + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer("SnmpContextv2c["); + buffer.append("host=").append(hostname); + buffer.append(", port=").append(hostPort); + buffer.append(", bindAddress=").append(bindAddr); + buffer.append(", socketType=").append(typeSocket); + buffer.append(", community=").append(community); + buffer.append(", #trapListeners=").append(trapSupport.getListenerCount()); + buffer.append(", #pduListeners=").append(pduSupport.getListenerCount()); + buffer.append("]"); + return buffer.toString(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cFace.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cFace.java new file mode 100644 index 0000000..9a90f2a --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cFace.java @@ -0,0 +1,67 @@ +// NAME +// $RCSfile: SnmpContextv2cFace.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.7 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This interface contains the SNMP context interface that is needed by every + * PDU to send a SNMP v2c request. + * + * @see SnmpContext + * + * @author Birgit Arkesteijn + * @version $Revision: 3.7 $ $Date: 2006/01/17 17:43:54 $ + */ +public interface SnmpContextv2cFace extends SnmpContextFace +{ + static final String version_id = + "@(#)$Id: SnmpContextv2cFace.java,v 3.7 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cPool.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cPool.java new file mode 100644 index 0000000..ae74a70 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv2cPool.java @@ -0,0 +1,211 @@ +// NAME +// $RCSfile: SnmpContextv2cPool.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.15 $ +// CREATED +// $Date: 2009/03/05 13:27:41 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; + +/** + * This class contains the pool of SNMP v2c contexts. + * It extends the SnmpContextPool and is similar in every way, except it + * uses a pool of SnmpContextv2c. + * + *

    + * Thanks to Seon Lee (slee@virtc.com) for reporting thread safety + * problems. + *

    + * + * @see SnmpContextv2c + * @see SnmpContextPool + * @see SnmpContextv3Pool + * + * @author Birgit Arkesteijn + * @version $Revision: 3.15 $ $Date: 2009/03/05 13:27:41 $ + */ +public class SnmpContextv2cPool extends SnmpContextPool + implements SnmpContextv2cFace +{ + private static final String version_id = + "@(#)$Id: SnmpContextv2cPool.java,v 3.15 2009/03/05 13:27:41 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see SnmpContextv2c#SnmpContextv2c(String, int) + */ +public SnmpContextv2cPool(String host, int port) throws java.io.IOException +{ + super(host, port, STANDARD_SOCKET); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param typeSocket The type of socket to use. + * + * @see SnmpContextv2c#SnmpContextv2c(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public SnmpContextv2cPool(String host, int port, String typeSocket) +throws java.io.IOException +{ + super(host, port, typeSocket); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param comm The community name. + * @param typeSocket The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * + * @since 4_14 + */ +public SnmpContextv2cPool(String host, int port, String comm, String typeSocket) +throws java.io.IOException +{ + super(host, port, comm, null, typeSocket); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param comm The community name. + * @param bindAddress The local address the server will bind to + * @param typeSocket The type of socket to use. + * + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * + * @since 4_14 + */ +public SnmpContextv2cPool(String host, int port, String comm, String bindAddress, String typeSocket) +throws java.io.IOException +{ + super(host, port, comm, bindAddress, typeSocket); +} + +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_2c; +} + +/** + * Returns a v2c context from the pool. + * The pre-existing context (if there is any) is destroyed. + * This methods checks for an existing context that matches all our + * properties. If such a context does not exist, a new one is created and + * added to the pool. + * + * This method actually returns a SnmpContextv2c, although it doesn't + * look like it. + * + * @return A context (v2c) from the pool + * @see #getHashKey + * @see SnmpContext + * @see SnmpContextv2c + */ +protected SnmpContext getMatchingContext() throws java.io.IOException +{ + SnmpContextPoolItem item = null; + SnmpContextv2c newContext = null; + String hashKey = getHashKey(); + + destroy(); + synchronized(contextPool) + { + int count=0; + if (contextPool.containsKey(hashKey)) + { + item = (SnmpContextPoolItem) contextPool.get(hashKey); + newContext = (SnmpContextv2c) item.getContext(); + count = item.getCounter(); + } + else + { + newContext = new SnmpContextv2c(hostname, hostPort, bindAddr, socketType); + newContext.setCommunity(community); + item = new SnmpContextPoolItem(newContext); + contextPool.put(hashKey, item); + } + count++; + item.setCounter(count); + } + return newContext; +} + +/** + * This method is not supported. It will throw a CloneNotSupportedException. + * + * @since 4_14 + */ +public Object clone() throws CloneNotSupportedException +{ + throw new CloneNotSupportedException(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3.java new file mode 100644 index 0000000..ca49bcc --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3.java @@ -0,0 +1,498 @@ +// NAME +// $RCSfile: SnmpContextv3.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.31 $ +// CREATED +// $Date: 2009/03/05 13:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.net.*; +import java.io.*; +import java.util.*; + +import uk.co.westhawk.snmp.pdu.*; +import uk.co.westhawk.snmp.util.*; +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.beans.*; + +/** + * This class contains the SNMP v3 context that is needed by every PDU to + * send a SNMP v3 request. + * Most of the work is done by SnmpContextv3Basis, like doing discovery. + * + *

    + * Now that the stack can send traps and receive requests, + * it needs to be able to act as an + * authoritative SNMP engine. This is done via the interface UsmAgent. + * The DefaultUsmAgent is not guaranteed to work; agents (or rather + * authoritative engines) should provide a better implementation. + *

    + * + *

    + * This class adds a UsmBeingDiscoveredBean as listener. This bean + * handles any incoming discovery PDU. Only when acting as + * authoritative engine should there be any discovery PDU. + *

    + * + * @see SnmpContextv3Face + * @see SnmpContextv3Pool + * @see TimeWindow + * @see DefaultUsmAgent + * @see UsmAgent + * @see #setUsmAgent(UsmAgent) + * @see UsmDiscoveryBean + * + * @author Birgit Arkesteijn + * @version $Revision: 3.31 $ $Date: 2009/03/05 13:12:50 $ + */ +public class SnmpContextv3 extends SnmpContextv3Basis +{ + private static final String version_id = + "@(#)$Id: SnmpContextv3.java,v 3.31 2009/03/05 13:12:50 birgita Exp $ Copyright Westhawk Ltd"; + + private UsmBeingDiscoveredBean myDiscBean = null; + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see AbstractSnmpContext#AbstractSnmpContext(String, int) + */ +public SnmpContextv3(String host, int port) throws IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The local address the server will bind to + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + */ +public SnmpContextv3(String host, int port, String typeSocketA) +throws IOException +{ + super(host, port, typeSocketA); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContextv3(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + super(host, port, bindAddress, typeSocketA); +} + + +/** + * Makes sure the UsmBeingDiscoveredBean is added as RequestPduListener, + * so that discovery requests are handled. When listening for incoming + * requests, the stack become authoritative. You have (!) to create a + * proper usmAgent so the stack can be discovered. + * + *

    + * Don't use the TCP_SOCKET when listening for request PDUs. It doesn't + * provide functionality to send a response back. + *

    + * + * @see #removeRequestPduListener(RequestPduListener, ListeningContextPool) + * @see UsmBeingDiscoveredBean + * @see SnmpContextv3Basis#setUsmAgent(UsmAgent) + * + * @param l The request PDU listener + * @param lcontext The listening context + */ +public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) +throws IOException +{ + super.addRequestPduListener(l, lcontext); + + if (myDiscBean == null) + { + myDiscBean = new UsmBeingDiscoveredBean(this, usmAgent); + } + myDiscBean.addRequestPduListener(lcontext); +} + + +/** + * Removes the UsmBeingDiscoveredBean as listener. + * + * @see #addRequestPduListener(RequestPduListener, ListeningContextPool) + * + * @param l The request PDU listener + * @param lcontext The listening context + */ +public void removeRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) +throws IOException +{ + super.removeRequestPduListener(l, lcontext); + if (myDiscBean != null) + { + myDiscBean.removeRequestPduListener(lcontext); + myDiscBean.freeResources(); + myDiscBean = null; + } +} + + +/** + * Processes an incoming PDU, that is not a Discovery PDU. + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * + *

    + * This method calls first processPotentialTrap and then + * processPotentialRequest. The reason this code is split up is because + * in one case the stack acts as authoritative engine and as non + * authoritative engine in the other.. + *

    + * + * @see #rawPduReceived + * @see #processPotentialTrap + * @see #processPotentialRequest + */ +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, IOException +{ + String msg = checkContextSanity(); + if (msg != null) + { + throw new DecodingException(msg); + } + int l = message.length; + byte [] copyOfMessage1 = new byte[l]; + byte [] copyOfMessage2 = new byte[l]; + System.arraycopy(message, 0, copyOfMessage1, 0, l); + System.arraycopy(message, 0, copyOfMessage2, 0, l); + + AsnDecoderv3 rpdu = new AsnDecoderv3(); + ByteArrayInputStream in = new ByteArrayInputStream(message); + AsnSequence asnTopSeq = rpdu.DecodeSNMPv3(in); + int msgId = rpdu.getMsgId(asnTopSeq); + + Pdu pdu = null; + + DecodingException encryptionDecodingException1 = null; + IOException encryptionIOException1 = null; + try + { + pdu = processPotentialTrap(rpdu, asnTopSeq, copyOfMessage1); + } + catch(DecodingException exc) + { + encryptionDecodingException1 = exc; + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialTrap(): DecodingException: " + + exc.getMessage()); + } + } + catch(IOException exc) + { + encryptionIOException1 = exc; + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialTrap(): IOException: " + + exc.getMessage()); + } + } + + DecodingException encryptionDecodingException2 = null; + IOException encryptionIOException2 = null; + if (pdu == null) + { + try + { + pdu = processPotentialRequest(rpdu, asnTopSeq, copyOfMessage2); + } + catch(DecodingException exc) + { + encryptionDecodingException2 = exc; + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialRequest(): DecodingException: " + + exc.getMessage()); + } + } + catch(IOException exc) + { + encryptionIOException2 = exc; + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialRequest(): IOException: " + + exc.getMessage()); + } + } + } + + + if (pdu != null) + { + pdu.snmpv3MsgId = new Integer(msgId); + } + else + { + if (encryptionIOException2 != null) + { + throw encryptionIOException2; + } + if (encryptionDecodingException2 != null) + { + throw encryptionDecodingException2; + } + if (encryptionIOException1 != null) + { + throw encryptionIOException1; + } + if (encryptionDecodingException1 != null) + { + throw encryptionDecodingException1; + } + } + return pdu; +} + + +/** + * Processes an incoming PDU, to see if it is a Trap. + * This method is called by processIncomingPdu. + * + * When receiving traps the stack is non authoritative. + * + * @see #processIncomingPdu + * @see #processPotentialRequest + * @since 4_14 + */ +public Pdu processPotentialTrap(AsnDecoderv3 rpdu, AsnSequence asnTopSeq, + byte [] message) +throws DecodingException, IOException +{ + // decode as Non Authoratative engine + AsnPduSequence pduSeq = rpdu.processSNMPv3(this, asnTopSeq, message, false); + Pdu pdu = null; + if (pduSeq != null) + { + byte type = pduSeq.getRespType(); + if (type == SnmpConstants.TRPV2_REQ_MSG) + { + pdu = new TrapPduv2(this); + pdu.fillin(pduSeq); + + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialTrap(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Not ignoring it!"); + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialTrap(): PDU received is not TRPV2_REQ_MSG" + + ". Ignoring it."); + } + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialTrap(): pduSeq == null" + + ". Ignoring it."); + } + } + return pdu; +} + + +/** + * Processes an incoming PDU, to see if it is a Request. + * This method is called by processIncomingPdu. + * + * When receiving pdu requests the stack is authoritative. + * + * @see #processIncomingPdu + * @see #processPotentialTrap + * @since 4_14 + */ +public Pdu processPotentialRequest(AsnDecoderv3 rpdu, AsnSequence asnTopSeq, + byte [] message) +throws DecodingException, IOException +{ + // decode as Authoratative engine + AsnPduSequence pduSeq = rpdu.processSNMPv3(this, asnTopSeq, message, true); + Pdu pdu = null; + if (pduSeq != null) + { + byte type = pduSeq.getRespType(); + if (type == SnmpConstants.GET_REQ_MSG && pduSeq.isSnmpv3Discovery() == true) + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".ProcessIncomingPdu(): received discovery pdu" + + ". Ignoring it."); + } + } + else + { + switch (type) + { + case SnmpConstants.GET_REQ_MSG: + pdu = new GetPdu(this); + pdu.fillin(pduSeq); + break; + case SnmpConstants.GETNEXT_REQ_MSG: + pdu = new GetNextPdu(this); + pdu.fillin(pduSeq); + break; + case SnmpConstants.SET_REQ_MSG: + pdu = new SetPdu(this); + pdu.fillin(pduSeq); + break; + case SnmpConstants.GETBULK_REQ_MSG: + pdu = new GetBulkPdu(this); + pdu.fillin(pduSeq); + break; + case SnmpConstants.INFORM_REQ_MSG: + pdu = new InformPdu(this); + pdu.fillin(pduSeq); + break; + //case SnmpConstants.GET_RSP_MSG: + // A lonely response should never be received here. + // They should come in via the processIncomingResponse + // route. + //case SnmpConstants.GET_RPRT_MSG: + // Reports are part of v3 timeliness communication. + //case SnmpConstants.TRPV2_REQ_MSG: + // Traps should have been decoded in + // processPotentialTrap() above + default: + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialRequest(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Ignoring it."); + } + } + + if (pdu != null) + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".processPotentialRequest(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Not ignoring it!"); + } + } + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + "..processPotentialRequest(): pduSeq == null" + + ". Ignoring it."); + } + } + return pdu; +} + + +/** + * Returns a clone of this SnmpContextv3. + * + * @exception CloneNotSupportedException Thrown when the constructor + * generates an IOException + */ +public Object clone() throws CloneNotSupportedException +{ + SnmpContextv3 clContext = null; + try + { + clContext = new SnmpContextv3(hostname, hostPort, bindAddr, typeSocket); + clContext = (SnmpContextv3) cloneParameters(clContext); + } + catch (IOException exc) + { + throw new CloneNotSupportedException("IOException " + + exc.getMessage()); + } + return clContext; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Basis.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Basis.java new file mode 100644 index 0000000..9eac387 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Basis.java @@ -0,0 +1,1159 @@ +// NAME +// $RCSfile: SnmpContextv3Basis.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.17 $ +// CREATED +// $Date: 2009/03/05 15:51:42 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.net.*; +import java.io.*; +import java.util.*; + +import uk.co.westhawk.snmp.pdu.*; +import uk.co.westhawk.snmp.util.*; +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.beans.*; + +/** + * This class contains the basis for the SNMP v3 contexts that is needed + * by every PDU to send a SNMP v3 request. + * + *

    + * This class will perform the v3 discovery of the SNMP engine ID and + * time line if necessary. This is done with the classes + * TimeWindow and UsmDiscoveryBean. + *

    + * + *

    + * Now that the stack can send traps and receive requests, + * it needs to be able to act as an + * authoritative SNMP engine. This is done via the interface UsmAgent. + * The DefaultUsmAgent is not guaranteed to work; agents (or rather + * authoritative engines) should provide a better implementation. + *

    + * + *

    + * This class will use the User Security Model (USM) as described in + * SNMP-USER-BASED-SM-MIB. + * See also RFC 3411. + *

    + * + *

    + * It is advised to set all the properties of this class before any PDU, + * using this class, is sent. + * All properties are being used to encode the message. Some properties are + * being used to decode the Response or Report PDU. + * When any of these last properties were changed in between flight there + * is a possibility the decoding fails, causing a + * DecodingException. + *

    + * + *

    + * destroy() should be called when the context is no longer + * used. This is the only way the threads will be stopped and garbage + * collected. + *

    + * + * @see SnmpContextv3Face + * @see SnmpContextv3Pool + * @see TimeWindow + * @see UsmAgent + * @see DefaultUsmAgent + * @see #setUsmAgent(UsmAgent) + * @see UsmDiscoveryBean + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.17 $ $Date: 2009/03/05 15:51:42 $ + */ +public abstract class SnmpContextv3Basis extends AbstractSnmpContext +implements SnmpContextv3Face, Cloneable +{ + private static final String version_id = + "@(#)$Id: SnmpContextv3Basis.java,v 3.17 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd"; + + protected String userName = Default_UserName; + protected boolean useAuthentication = false; + protected String userAuthenticationPassword; + protected byte[] userAuthKeyMD5 = null; + protected byte[] userAuthKeySHA1 = null; + protected int authenticationProtocol = MD5_PROTOCOL; + protected int privacyProtocol = DES_ENCRYPT ; + protected boolean usePrivacy = false; + protected String userPrivacyPassword; + protected byte[] userPrivKeyMD5 = null; + protected byte[] userPrivKeySHA1 = null; + protected byte [] contextEngineId = new byte[0]; + protected String contextName = Default_ContextName; + protected UsmAgent usmAgent = null; + + private Hashtable msgIdHash = new Hashtable(MAXPDU); + private static int next_id = 1; + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see AbstractSnmpContext#AbstractSnmpContext(String, int) + */ +public SnmpContextv3Basis(String host, int port) throws IOException +{ + this(host, port, null, STANDARD_SOCKET); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The local address the server will bind to + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + */ +public SnmpContextv3Basis(String host, int port, String typeSocketA) +throws IOException +{ + this(host, port, null, typeSocketA); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContextv3Basis(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + super(host, port, bindAddress, typeSocketA); + + if (TimeWindow.getCurrent() == null) + { + TimeWindow timew = new TimeWindow(); + } + setUsmAgent(createUsmAgent()); +} + +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_3; +} + +/** + * Returns the username. + * + * @return the username + */ +public String getUserName() +{ + return userName; +} + +/** + * Sets the username. + * This username will be used for all PDUs sent with this context. + * The username corresponds to the 'msgUserName' in + * SNMP-USER-BASED-SM-MIB. + * The default value is "initial". + * + * @param newUserName The new username + * @see #Default_UserName + */ +public void setUserName(String newUserName) +{ + userName = newUserName; +} + +/** + * Returns if authentication is used or not. + * By default no authentication will be used. + * + * @return true if authentication is used, false if not + */ +public boolean isUseAuthentication() +{ + return useAuthentication; +} + +/** + * Sets whether authentication has to be used. + * By default no authentication will be used. + * + * @param newUseAuthentication The use of authentication + */ +public void setUseAuthentication(boolean newUseAuthentication) +{ + useAuthentication = newUseAuthentication; +} + +/** + * Returns the user authentication password. + * This password will be transformed into the user authentication secret key. + * + * @return The user authentication password + */ +public String getUserAuthenticationPassword() +{ + return userAuthenticationPassword; +} + +/** + * Sets the user authentication password. + * This password will be transformed into the user authentication secret + * key. A user MUST set this password. + * + * @param newUserAuthPassword The user authentication password + */ +public void setUserAuthenticationPassword(String newUserAuthPassword) +{ + if (newUserAuthPassword != null + && + newUserAuthPassword.equals(userAuthenticationPassword) == false) + { + userAuthenticationPassword = newUserAuthPassword; + userAuthKeyMD5 = null; + userAuthKeySHA1 = null; + } +} + +/** + * Sets the protocol to be used for authentication. + * This can either be MD5 or SHA-1. + * By default MD5 will be used. + * + * @param protocol The authentication protocol to be used + * @see #MD5_PROTOCOL + * @see #SHA1_PROTOCOL + */ +public void setAuthenticationProtocol(int protocol) +throws IllegalArgumentException +{ + if (protocol == MD5_PROTOCOL || protocol == SHA1_PROTOCOL) + { + if (protocol != authenticationProtocol) + { + authenticationProtocol = protocol; + } + } + else + { + throw new IllegalArgumentException("Authentication Protocol " + + "should be MD5 or SHA1"); + } +} + +/** + * Returns the protocol to be used for authentication. + * This can either be MD5 or SHA-1. + * By default MD5 will be used. + * + * @return The authentication protocol to be used + * @see #MD5_PROTOCOL + * @see #SHA1_PROTOCOL + */ +public int getAuthenticationProtocol() +{ + return authenticationProtocol; +} + +/** + * Sets the protocol to be used for privacy. + * This can either be DES or AES. + * By default DES will be used. + * + * @param protocol The privacy protocol to be used + * @see SnmpContextv3Face#AES_ENCRYPT + * @see SnmpContextv3Face#DES_ENCRYPT + */ +public void setPrivacyProtocol(int protocol) +throws IllegalArgumentException +{ + if (protocol == DES_ENCRYPT || protocol == AES_ENCRYPT) + { + if (protocol != privacyProtocol) + { + privacyProtocol = protocol; + } + } + else + { + throw new IllegalArgumentException("Privacy Encryption " + + "should be AES or DES"); + } +} + +/** + * Returns the protocol to be used for privacy. + * This can either be DES or AES. + * By default DES will be used. + * + * @return The privacy protocol to be used + * @see SnmpContextv3Face#AES_ENCRYPT + * @see SnmpContextv3Face#DES_ENCRYPT + */ +public int getPrivacyProtocol() +{ + return privacyProtocol; +} + +byte[] getAuthenticationPasswordKeyMD5() +{ + if (userAuthKeyMD5 == null) + { + userAuthKeyMD5 = SnmpUtilities.passwordToKeyMD5(userAuthenticationPassword); + } + return userAuthKeyMD5; +} + +byte[] getAuthenticationPasswordKeySHA1() +{ + if (userAuthKeySHA1 == null) + { + userAuthKeySHA1 = SnmpUtilities.passwordToKeySHA1(userAuthenticationPassword); + } + return userAuthKeySHA1; +} + + +byte[] getPrivacyPasswordKeyMD5() +{ + if (userPrivKeyMD5 == null) + { + userPrivKeyMD5 = SnmpUtilities.passwordToKeyMD5(userPrivacyPassword); + } + return userPrivKeyMD5; +} + +byte[] getPrivacyPasswordKeySHA1() +{ + if (userPrivKeySHA1 == null) + { + userPrivKeySHA1 = SnmpUtilities.passwordToKeySHA1(userPrivacyPassword); + } + return userPrivKeySHA1; +} + + +/** + * Returns if privacy is used or not. + * By default privacy is not used. + * + * @return true if privacy is used, false if not + */ +public boolean isUsePrivacy() +{ + return usePrivacy; +} + +/** + * Sets whether privacy has to be used. + * By default privacy is not used. + * Note, privacy (encryption) without authentication is not allowed. + * + * @param newUsePrivacy The use of privacy + */ +public void setUsePrivacy(boolean newUsePrivacy) +{ + usePrivacy = newUsePrivacy; +} + +/** + * Returns the user privacy password. + * This password will be transformed into the user privacy secret key. + * + * @return The user privacy password + */ +public String getUserPrivacyPassword() +{ + return userPrivacyPassword; +} + + +/** + * Sets the user privacy password. + * This password will be transformed into the user privacy secret + * key. A user must set this password in order to use privacy. + * + * @param newUserPrivacyPassword The user privacy password + */ +public void setUserPrivacyPassword(String newUserPrivacyPassword) +{ + if (newUserPrivacyPassword != null + && + newUserPrivacyPassword.equals(userPrivacyPassword) == false) + { + userPrivacyPassword = newUserPrivacyPassword; + userPrivKeyMD5 = null; + userPrivKeySHA1 = null; + } +} + + +/** + * Sets the contextEngineID. + * See RFC 3411. + * + * A contextEngineID uniquely + * identifies an SNMP entity that may realize an instance of a context + * with a particular contextName. + * + *

    + * Note, when the stack is an authoritative engine, this parameter should + * equal the UsmAgent.getSnmpEngineId(). See the StackUsage + * documentation for an explanation. + *

    + * + *

    + * If the contextEngineID is of length zero, the encoder will use the (discovered) + * snmpEngineId. + *

    + * + * @see UsmAgent#getSnmpEngineId() + * @param newContextEngineId The contextEngineID + */ +public void setContextEngineId(byte [] newContextEngineId) +throws IllegalArgumentException +{ + if (newContextEngineId != null) + { + contextEngineId = newContextEngineId; + } + else + { + throw new IllegalArgumentException("contextEngineId is null"); + } +} + +/** + * Returns the contextEngineID. + * + * @return The contextEngineID + */ +public byte [] getContextEngineId() +{ + return contextEngineId; +} + +/** + * Sets the contextName. + * See RFC 3411. + * + * A contextName is used to name a context. Each contextName MUST be + * unique within an SNMP entity. + * By default this is "" (the empty String). + * + * @param newContextName The contextName + * @see #Default_ContextName + */ +public void setContextName(String newContextName) +{ + contextName = newContextName; +} + +/** + * Returns the contextName. + * + * @return The contextName + */ +public String getContextName() +{ + return contextName; +} + +/** + * Adds a discovery pdu. This method adds the PDU (without checking if + * discovery is needed). + * + * @param pdu the discovery pdu + * @return pdu is succesful added + * @see AbstractSnmpContext#addPdu(Pdu) + * @see #addPdu(Pdu) + */ +public boolean addDiscoveryPdu(DiscoveryPdu pdu) +throws IOException, PduException +{ + // since this is a DiscoveryPdu we do not check for discovery :-) + return this.addPdu(pdu, false); +} + +/** + * Adds a PDU. This method adds the PDU and blocks until it has all the + * discovery parameters it needs. + * + * @param pdu the PDU + * @return pdu is succesful added + * @see AbstractSnmpContext#addPdu(Pdu) + * @see #addDiscoveryPdu(DiscoveryPdu) + */ +public boolean addPdu(Pdu pdu) +throws IOException, PduException +{ + return this.addPdu(pdu, true); +} + +/** + * Creates the USM agent. + * @see DefaultUsmAgent + * @see #isAuthoritative + */ +protected UsmAgent createUsmAgent() +{ + return new DefaultUsmAgent(); +} + +/** + * Sets the UsmAgent, needed when this stack is used as authoritative + * SNMP engine. This interface provides authentiation details, like its + * clock and its Engine ID. + * + * @see DefaultUsmAgent + * @param agent The USM authoritative interface + * @since 4_14 + */ +public void setUsmAgent(UsmAgent agent) +{ + usmAgent = agent; +} + +/** + * Returns the UsmAgent. + * @see #setUsmAgent + * @since 4_14 + */ +public UsmAgent getUsmAgent() +{ + return usmAgent; +} + +/** + * Adds a PDU. This method adds the PDU and checks if discovery is + * needed depending on the parameter checkDiscovery. + * If discovery is needed this method will block until it has done so. + * Discovery is only needed if the stack is non authoritative. + * + *

    + * This method stores the SNMPv3 msgId and PDU + * request id in a Hashtable. + * Since the encoding only happens once and every retry sends the same + * encoded packet, only one msgId is used. + *

    + * + * @param pdu the PDU + * @param checkDiscovery check if discovery is needed + * @return pdu is succesful added + * @see AbstractSnmpContext#addPdu(Pdu) + * @see #addDiscoveryPdu(DiscoveryPdu) + * @see #addPdu(Pdu) + */ +protected boolean addPdu(Pdu pdu, boolean checkDiscovery) +throws IOException, PduException +{ + // TODO, when sending response or report, the msgId should be set! + Integer msgId = pdu.snmpv3MsgId; + if (msgId == null) + { + msgId = new Integer(next_id++); + } + else if (pdu.isExpectingResponse() == true) + { + // generate a new msgId, even if this is already set. The user + // could be adding the same PDU more than once to the + // context. + msgId = new Integer(next_id++); + } + pdu.snmpv3MsgId = msgId; + + msgIdHash.put(msgId, new Integer(pdu.req_id)); + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".addPdu(): msgId=" + + msgId.toString() + ", Pdu reqId=" + pdu.req_id); + } + + if (checkDiscovery == true && isAuthoritative(pdu.getMsgType()) == false) + { + discoverIfNeeded(pdu); + } + + boolean added = super.addPdu(pdu); + return added; +} + +/** + * Removes a PDU. This removes the PDU from the AbstractSnmpContext and + * clears the link with the SNMPv3 msgId. + * + * @param rid the PDU request id + * @return whether the PDU has been successfully removed + * @see AbstractSnmpContext#removePdu(int) + */ +public synchronized boolean removePdu(int rid) +{ + boolean removed = super.removePdu(rid); + if (removed) + { + Enumeration keys = msgIdHash.keys(); + Integer msgIdI = null; + boolean found = false; + while (keys.hasMoreElements() && found == false) + { + msgIdI = (Integer) keys.nextElement(); + Integer pduIdI = (Integer) msgIdHash.get(msgIdI); + found = (pduIdI.intValue() == rid); + } + if (found) + { + msgIdHash.remove(msgIdI); + } + } + return removed; +} + +/** + * Encodes a discovery PDU packet. This methods encodes without checking + * if the discovery parameters are all known. + */ +public byte[] encodeDiscoveryPacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws IOException, EncodingException +{ + String engineId = ""; + TimeWindow tWindow = TimeWindow.getCurrent(); + if (tWindow.isSnmpEngineIdKnown(getSendToHostAddress(), hostPort) == true) + { + engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort); + } + TimeWindowNode node = new TimeWindowNode(engineId, 0, 0); + + return actualEncodePacket(msg_type, rId, errstat, errind, ve, node, + obj); +} + +/** + * Encodes a PDU. This is for internal use only and should + * NOT be called by the developer. + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * + *

    + * When the stack is + *

    + *
      + *
    • + * authoritative, the timeline details are retrieved from the UsmAgent. + *
    • + *
    • + * non authoritative, this methods first checks if all the discovery + * parameters are known; + *
        + *
      • + * If so, it encodes and returns the bytes. + *
      • + *
      • + * If not, it will throw an EncodingException. + *
      • + *
      + *
    • + *
    + * + * @see #isAuthoritative(byte) + * @param msg_type The message type + * @param rId The message id + * @param errstat The error status + * @param errind The error index + * @param ve The varbind list + * @param obj Additional object (only used in SNMPv3) + * @return The encoded packet + */ +public byte[] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws IOException, EncodingException +{ + TimeWindowNode node = null; + if (isDestroyed == true) + { + throw new EncodingException("Context can no longer be used, since it is already destroyed"); + } + else + { + TimeWindow tWindow = TimeWindow.getCurrent(); + if (isAuthoritative(msg_type) == true) + { + usmAgent.setSnmpContext(this); + if (usmAgent.getSnmpEngineId() == null) + { + throw new EncodingException("UsmAgent " + + usmAgent.getClass().getName() + + " should provide Engine ID!"); + } + tWindow.updateTimeWindow(usmAgent.getSnmpEngineId(), + usmAgent.getSnmpEngineBoots(), usmAgent.getSnmpEngineTime(), + this.isUseAuthentication()); + node = tWindow.getTimeLine(usmAgent.getSnmpEngineId()); + } + else + { + if (tWindow.isSnmpEngineIdKnown(getSendToHostAddress(), hostPort) == false) + { + throw new EncodingException("Engine ID of host " + + getSendToHostAddress() + + ", port " + hostPort + + " is unknown (rId=" + + rId + "). Perform discovery."); + } + String engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort); + node = new TimeWindowNode(engineId, 0, 0); + + if (isUseAuthentication()) + { + if (tWindow.isTimeLineKnown(engineId) == true) + { + node = tWindow.getTimeLine(engineId); + } + else + { + throw new EncodingException("Time Line of Engine ID of host " + + getSendToHostAddress() + ", port " + hostPort + " is unknown. " + + "Perform discovery."); + } + } + } + } + return actualEncodePacket(msg_type, rId, errstat, errind, ve, node, + obj); +} + + +/** + * Checks the sanity of the context and returns an error message when it + * is not correct. + */ +protected String checkContextSanity() +{ + String ret = null; + if (usePrivacy == true) + { + if (userPrivacyPassword == null) + { + ret = "userPrivacyPassword is null, but usePrivacy is true"; + } + else if (userPrivacyPassword.length() == 0) + { + ret = "userPrivacyPassword is empty, but usePrivacy is true"; + } + else if (useAuthentication == false) + { + ret = "useAuthentication is false, but usePrivacy is true"; + } + } + + if (useAuthentication == true) + { + if (userAuthenticationPassword == null) + { + ret = "userAuthenticationPassword is null, but useAuthentication is true"; + } + else if (userAuthenticationPassword.length() == 0) + { + ret = "userAuthenticationPassword is empty, but useAuthentication is true"; + } + } + return ret; +} + + +/** + * Does the actual encoding. + * + * @see #encodeDiscoveryPacket + * @see #encodePacket + */ +protected byte[] actualEncodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, TimeWindowNode node, Object obj) + throws IOException, EncodingException +{ + AsnEncoderv3 enc = new AsnEncoderv3(); + String msg = checkContextSanity(); + if (msg != null) + { + throw new EncodingException(msg); + } + + int msgId = ((Integer)obj).intValue(); + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".actualEncodePacket(): msgId=" + + msgId + ", Pdu reqId=" + rId); + } + byte[] packet = enc.EncodeSNMPv3(this, msgId, node, + msg_type, rId, errstat, errind, ve); + + return packet; +} + +/** + * Processes an incoming SNMP v3 response. + */ +protected void processIncomingResponse(ByteArrayInputStream in) +throws DecodingException, IOException +{ + AsnDecoderv3 rpdu = new AsnDecoderv3(); + // don't have to check for context sanity here: if the request was + // fine, so should be the response + byte [] bu = null; + // need to duplicate the message for V3 to rewrite + int nb = in.available(); + bu = new byte[nb]; + in.read(bu); + in = new ByteArrayInputStream(bu); + + AsnSequence asnTopSeq = rpdu.DecodeSNMPv3(in); + int msgId = rpdu.getMsgId(asnTopSeq); + Integer rid = (Integer) msgIdHash.get(new Integer(msgId)); + if (rid != null) + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): msgId=" + + msgId + ", Pdu reqId=" + rid); + } + Pdu pdu = getPdu(rid); + try + { + AsnPduSequence pduSeq = rpdu.processSNMPv3(this, asnTopSeq, bu, false); + if (pduSeq != null) + { + // got a message + Integer rid2 = new Integer(pduSeq.getReqId()); + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".processIncomingResponse():" + + " rid2=" + rid2); + } + + Pdu newPdu = null; + if (rid2.intValue() != rid.intValue()) + { + newPdu = getPdu(rid2); + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): " + + "pduReqId of msgId (" + rid.intValue() + + ") != pduReqId of Pdu (" + rid2.intValue() + + ")"); + } + if (newPdu == null) + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): " + + "Using pduReqId of msgId (" + rid.intValue() + ")"); + } + } + } + + if (newPdu != null) + { + pdu = newPdu; + } + } + else + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".processIncomingResponse():" + + " pduSeq is null."); + } + } + + if (pdu != null) + { + pdu.fillin(pduSeq); + } + else + { + if (AsnObject.debug > 6) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): No Pdu with reqid " + rid.intValue()); + } + } + } + catch (DecodingException exc) + { + if (pdu != null) + { + pdu.setErrorStatus(AsnObject.SNMP_ERR_DECODING_EXC, exc); + pdu.fillin(null); + } + else + { + throw exc; + } + } + } + else + { + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + ".processIncomingResponse(): Pdu of msgId " + msgId + + " is already answered"); + } + rid = new Integer(-1); + } +} + +/** + * Returns if we send this PDU in authoritative role or not. + * The engine who sends a Response, a Trapv2 or a Report is + * authoritative. + * + * @since 4_14 + * @return true if authoritative, false if not. + */ +// Note: for when adding INFORM +// When sending an INFORM, the receiver is the authoritative engine, so +// the INFORM does NOT have to be added to this list! +protected boolean isAuthoritative(byte msg_type) +{ + return (msg_type == AsnObject.GET_RSP_MSG + || + msg_type == AsnObject.TRPV2_REQ_MSG + || + msg_type == AsnObject.GET_RPRT_MSG); +} + +void discoverIfNeeded(Pdu pdu) +throws IOException, PduException +{ + UsmDiscoveryBean discBean = null; + boolean isNeeded = false; + + TimeWindow tWindow = TimeWindow.getCurrent(); + String engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort); + if (engineId == null) + { + isNeeded = true; + discBean = new UsmDiscoveryBean( + getSendToHostAddress(), hostPort, bindAddr, typeSocket); + discBean.setRetryIntervals(pdu.getRetryIntervals()); + } + + if (isUseAuthentication()) + { + if (isNeeded) + { + discBean.setAuthenticationDetails(userName, + userAuthenticationPassword, authenticationProtocol); + } + else if (tWindow.isTimeLineKnown(engineId) == false) + { + isNeeded = true; + discBean = new UsmDiscoveryBean( + getSendToHostAddress(), hostPort, bindAddr, typeSocket); + discBean.setAuthenticationDetails(userName, + userAuthenticationPassword, authenticationProtocol); + discBean.setRetryIntervals(pdu.getRetryIntervals()); + } + + if (isNeeded && isUsePrivacy()) + { + discBean.setPrivacyDetails(userPrivacyPassword, privacyProtocol); + } + } + + if (isNeeded) + { + discBean.startDiscovery(); + + } + + // If contextEngineId is null or of length zero, set + // it to the snmpEngineId. + if (contextEngineId == null || contextEngineId.length == 0) + { + engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort); + setContextEngineId(SnmpUtilities.toBytes(engineId)); + } +} + + +/** + * Adds the specified request pdu listener to receive PDUs on the + * specified listening context that matches this context. + * This method will call usmAgent.setSnmpContext(this). + * + *

    + * Don't use the TCP_SOCKET when listening for request PDUs. It doesn't + * provide functionality to send a response back. + *

    + * + * @see AbstractSnmpContext#addRequestPduListener(RequestPduListener, ListeningContextPool) + * + * @param l The request PDU listener + * @param lcontext The listening context + */ +public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) +throws IOException +{ + super.addRequestPduListener(l, lcontext); + + usmAgent.setSnmpContext(this); + TimeWindow tWindow = TimeWindow.getCurrent(); + if (usmAgent.getSnmpEngineId() == null) + { + throw new IOException("UsmAgent " + + usmAgent.getClass().getName() + + " should provide Engine ID!"); + } + tWindow.setSnmpEngineId(usmAgent.MYFAKEHOSTNAME, hostPort, usmAgent.getSnmpEngineId()); + tWindow.updateTimeWindow(usmAgent.getSnmpEngineId(), + usmAgent.getSnmpEngineBoots(), usmAgent.getSnmpEngineTime(), + this.isUseAuthentication()); +} + + + +/** + * Copies all parameters into another SnmpContextv3. + */ +public Object cloneParameters(SnmpContextv3Face clContext) +{ + clContext.setUserName(new String(userName)); + clContext.setUseAuthentication(useAuthentication); + if (userAuthenticationPassword != null) + { + clContext.setUserAuthenticationPassword( + new String(userAuthenticationPassword)); + } + clContext.setAuthenticationProtocol(authenticationProtocol); + + clContext.setUsePrivacy(usePrivacy); + if (userPrivacyPassword != null) + { + clContext.setUserPrivacyPassword(new String(userPrivacyPassword)); + } + clContext.setPrivacyProtocol(privacyProtocol); + + clContext.setContextName(new String(contextName)); + + int l = contextEngineId.length; + byte[] newContextEngineId = new byte[l]; + System.arraycopy(contextEngineId, 0, newContextEngineId, 0, l); + clContext.setContextEngineId(newContextEngineId); + + clContext.setUsmAgent(usmAgent); + return clContext; +} + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for a hashtable of (v3) contexts. + * + * @since 4_14 + * @return The hash key + */ +public String getHashKey() +{ + StringBuffer buffer = new StringBuffer(); + buffer.append(hostname); + buffer.append("_").append(hostPort); + buffer.append("_").append(bindAddr); + buffer.append("_").append(typeSocket); + buffer.append("_").append(useAuthentication); + buffer.append("_").append(ProtocolNames[authenticationProtocol]); + buffer.append("_").append(ProtocolNames[privacyProtocol]); + buffer.append("_").append(userAuthenticationPassword); + buffer.append("_").append(userName); + buffer.append("_").append(usePrivacy); + buffer.append("_").append(userPrivacyPassword); + buffer.append("_").append(SnmpUtilities.toHexString(contextEngineId)); + buffer.append("_").append(contextName); + buffer.append("_v").append(getVersion()); + + return buffer.toString(); +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer(getClass().getName() + "["); + buffer.append("host=").append(hostname); + buffer.append(", sendToHost=").append(getSendToHostAddress()); + buffer.append(", port=").append(hostPort); + buffer.append(", bindAddress=").append(bindAddr); + buffer.append(", socketType=").append(typeSocket); + buffer.append(", contextEngineId=").append(SnmpUtilities.toHexString(contextEngineId)); + buffer.append(", contextName=").append(contextName); + buffer.append(", userName=").append(userName); + buffer.append(", useAuthentication=").append(useAuthentication); + buffer.append(", authenticationProtocol=").append(ProtocolNames[authenticationProtocol]); + buffer.append(", userAuthenticationPassword=").append(userAuthenticationPassword); + buffer.append(", usePrivacy=").append(usePrivacy); + buffer.append(", privacyProtocol=").append(ProtocolNames[privacyProtocol]); + buffer.append(", userPrivacyPassword=").append(userPrivacyPassword); + buffer.append(", #trapListeners=").append(trapSupport.getListenerCount()); + buffer.append(", #pduListeners=").append(pduSupport.getListenerCount()); + buffer.append("]"); + return buffer.toString(); +} + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Discovery.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Discovery.java new file mode 100644 index 0000000..c89b52a --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Discovery.java @@ -0,0 +1,224 @@ +// NAME +// $RCSfile: SnmpContextv3Discovery.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.11 $ +// CREATED +// $Date: 2009/03/05 13:12:50 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2005 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.net.*; +import java.io.*; +import java.util.*; + +import uk.co.westhawk.snmp.pdu.*; +import uk.co.westhawk.snmp.util.*; +import uk.co.westhawk.snmp.event.*; +import uk.co.westhawk.snmp.beans.*; + +/** + * This class contains the SNMP v3 discovery context that is used by + * UsmBeingDiscoveredBean, when this stack is being discovered. + * Most of the work is done by SnmpContextv3Basis. + * + *

    + * Now that the stack can send traps and receive requests, + * it needs to be able to act as an + * authoritative SNMP engine. This is done via the interface UsmAgent. + * The DefaultUsmAgent is not guaranteed to work; agents (or rather + * authoritative engines) should provide a better implementation. + *

    + * + * @see DefaultUsmAgent + * @see UsmBeingDiscoveredBean + * + * @since 4_14 + * @author Birgit Arkesteijn + * @version $Revision: 3.11 $ $Date: 2009/03/05 13:12:50 $ + */ +public class SnmpContextv3Discovery extends SnmpContextv3Basis +{ + private static final String version_id = + "@(#)$Id: SnmpContextv3Discovery.java,v 3.11 2009/03/05 13:12:50 birgita Exp $ Copyright Westhawk Ltd"; + + +/** + * Constructor. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see AbstractSnmpContext#AbstractSnmpContext(String, int) + */ +public SnmpContextv3Discovery(String host, int port) throws IOException +{ + super(host, port); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the Pdu will be sent + * @param port The port where the SNMP server will be + * @param typeSocketA The local address the server will bind to + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String) + */ +public SnmpContextv3Discovery(String host, int port, String typeSocketA) +throws IOException +{ + super(host, port, typeSocketA); +} + +/** + * Constructor. + * Parameter typeSocketA should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocketA The type of socket to use. + * + * @see AbstractSnmpContext#AbstractSnmpContext(String, int, String, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * @since 4_14 + */ +public SnmpContextv3Discovery(String host, int port, String bindAddress, String typeSocketA) +throws IOException +{ + super(host, port, bindAddress, typeSocketA); +} + + +/** + * Processes an incoming Discovery (and only Discovery) PDU. + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * + * @see #rawPduReceived + */ +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, IOException +{ + String msg = checkContextSanity(); + if (msg != null) + { + throw new DecodingException(msg); + } + int l = message.length; + byte [] copyOfMessage = new byte[l]; + System.arraycopy(message, 0, copyOfMessage, 0, l); + + AsnDecoderv3 rpdu = new AsnDecoderv3(); + ByteArrayInputStream in = new ByteArrayInputStream(message); + AsnSequence asnTopSeq = rpdu.DecodeSNMPv3(in); + int msgId = rpdu.getMsgId(asnTopSeq); + AsnPduSequence pduSeq = rpdu.processSNMPv3(this, asnTopSeq, copyOfMessage, true); + + Pdu pdu = null; + if (pduSeq != null) + { + byte type = pduSeq.getRespType(); + if (type == SnmpConstants.GET_REQ_MSG && pduSeq.isSnmpv3Discovery() == true) + { + pdu = new GetPdu(this); + } + else + { + /* + These cannot be sent as discovery pdu; + SnmpConstants.GETNEXT_REQ_MSG + SnmpConstants.SET_REQ_MSG + SnmpConstants.GETBULK_REQ_MSG + SnmpConstants.INFORM_REQ_MSG + SnmpConstants.GET_RSP_MSG + SnmpConstants.GET_RPRT_MSG + SnmpConstants.TRPV2_REQ_MSG + */ + + if (AsnObject.debug > 3) + { + System.out.println(getClass().getName() + + ".ProcessIncomingPdu(): PDU received with type " + + pduSeq.getRespTypeString() + + ". Ignoring it."); + } + } + + if (pdu != null) + { + pdu.fillin(pduSeq); + pdu.snmpv3MsgId = new Integer(msgId); + } + } + return pdu; +} + +/** + * Returns a clone of this SnmpContextv3. + * + * @exception CloneNotSupportedException Thrown when the constructor + * generates an IOException + */ +public Object clone() throws CloneNotSupportedException +{ + SnmpContextv3Discovery clContext = null; + try + { + clContext = new SnmpContextv3Discovery(hostname, hostPort, bindAddr, typeSocket); + clContext = (SnmpContextv3Discovery) cloneParameters(clContext); + } + catch (IOException exc) + { + throw new CloneNotSupportedException("IOException " + + exc.getMessage()); + } + return clContext; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Face.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Face.java new file mode 100644 index 0000000..3de4522 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Face.java @@ -0,0 +1,361 @@ +// NAME +// $RCSfile: SnmpContextv3Face.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.20 $ +// CREATED +// $Date: 2009/03/05 12:56:17 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import uk.co.westhawk.snmp.pdu.*; + +/** + * This interface contains the SNMP context interface that is needed by every + * PDU to send a SNMP v3 request. + * + * See SNMP-USER-BASED-SM-MIB, + * RFC 3411, + * RFC 3826 (AES) + * + * @author Birgit Arkesteijn + * @version $Revision: 3.20 $ $Date: 2009/03/05 12:56:17 $ + */ +public interface SnmpContextv3Face extends SnmpContextBasisFace +{ + static final String version_id = + "@(#)$Id: SnmpContextv3Face.java,v 3.20 2009/03/05 12:56:17 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * The SNMPv1 security model. This has value 1. + * The stack does not implement this security model. + */ + public final static int SNMPv1_Security_Model = (byte)(0x1); + + /** + * The SNMPv2c security model. This has value 2. + * The stack does not implement this security model. + */ + public final static int SNMPv2c_Security_Model = (byte)(0x2); + + /** + * The USM security model. This has value 3. + * This stack only implements this security model! + */ + public final static int USM_Security_Model = (byte)(0x3); + + /** + * The MD5 protocol type. + */ + public final static int MD5_PROTOCOL=0; + + /** + * The SHA-1 protocol type. + */ + public final static int SHA1_PROTOCOL=1; + + /** + * The DES encryption type. + */ + public final static int DES_ENCRYPT=2; + + /** + * The AES 128 encryption type. + */ + public final static int AES_ENCRYPT=3; + + /** + * The default value for the (security) user name. This is + * "initial". + */ + public final static String Default_UserName = "initial"; + + /** + * The default Context Name. This is the zero length string, i.e. "". + */ + public final static String Default_ContextName = ""; + + /** + * The array with the String represensations of the protocols. + */ + public final static String ProtocolNames [] = + { + "MD5", + "SHA1", + "DES", + "AES" + }; + +/** + * Returns the username. + * + * @return the username + */ +public String getUserName(); + +/** + * Sets the username. + * This username will be used for all PDUs sent with this context. + * The username corresponds to the 'msgUserName' in + * SNMP-USER-BASED-SM-MIB. + * The default value is "initial". + * + * @param newUserName The new username + */ +public void setUserName(String newUserName); + +/** + * Returns if authentication is used or not. + * By default no authentication will be used. + * + * @return true if authentication is used, false if not + */ +public boolean isUseAuthentication(); + +/** + * Sets whether authentication has to be used. + * By default no authentication will be used. + * + * @param newUseAuthentication The use of authentication + */ +public void setUseAuthentication(boolean newUseAuthentication); + +/** + * Returns the user authentication password. + * This password will be transformed into the user authentication secret key. + * + * @return The user authentication password + */ +public String getUserAuthenticationPassword(); + +/** + * Sets the user authentication password. + * This password will be transformed into the user authentication secret + * key. A user MUST set this password. + * + * @param newUserAuthPassword The user authentication password + */ +public void setUserAuthenticationPassword(String newUserAuthPassword) +throws IllegalArgumentException; + +/** + * Sets the protocol to be used for authentication. + * This can either be MD5 or SHA-1. + * By default MD5 will be used. + * + * @param protocol The authentication protocol to be used + * @see #MD5_PROTOCOL + * @see #SHA1_PROTOCOL + */ +public void setAuthenticationProtocol(int protocol) +throws IllegalArgumentException; + +/** + * Returns the protocol to be used for authentication. + * This can either be MD5 or SHA-1. + * By default MD5 will be used. + * + * @return The authentication protocol to be used + * @see #MD5_PROTOCOL + * @see #SHA1_PROTOCOL + */ +public int getAuthenticationProtocol(); + +/** + * Sets the protocol to be used for privacy. + * This can either be DES or AES. + * By default DES will be used. + * + * @param protocol The privacy protocol to be used + * @see #DES_ENCRYPT + * @see #AES_ENCRYPT + */ +public void setPrivacyProtocol(int protocol) +throws IllegalArgumentException; + +/** + * Returns the protocol to be used for privacy. + * This can either be DES or AES. + * By default DES will be used. + * + * @return The privacy protocol to be used + * @see #DES_ENCRYPT + * @see #AES_ENCRYPT + */ +public int getPrivacyProtocol(); + +/** + * Returns if privacy is used or not. + * By default no privacy will be used. + * + * @return true if privacy is used, false if not + */ +public boolean isUsePrivacy(); + +/** + * Sets whether privacy has to be used. + * By default no privacy will be used. + * + * @param newUsePrivacy The use of privacy + */ +public void setUsePrivacy(boolean newUsePrivacy); + +/** + * Returns the user privacy password. + * This password will be transformed into the user privacy secret key. + * + * @return The user privacy password + */ +public String getUserPrivacyPassword(); + +/** + * Sets the user privacy password. + * This password will be transformed into the user privacy secret + * key. A user MUST set this password. + * + * @param newUserAuthPassword The user privacy password + */ +public void setUserPrivacyPassword(String newUserAuthPassword) +throws IllegalArgumentException; + + +/** + * Sets the contextEngineID. + * See RFC 3411. + * + * A contextEngineID uniquely + * identifies an SNMP entity that may realize an instance of a context + * with a particular contextName. + * + *

    + * Note, when the stack is an authoritative engine, this parameter should + * equal the UsmAgent.getSnmpEngineId(). See the StackUsage + * documentation for an explanation. + *

    + * + *

    + * If the contextEngineID is of length zero, the encoder will use the (discovered) + * snmpEngineId. + *

    + * + * @see UsmAgent#getSnmpEngineId() + * @param newContextEngineId The contextEngineID + */ +public void setContextEngineId(byte [] newContextEngineId) +throws IllegalArgumentException; + +/** + * Returns the contextEngineID. + * + * @return The contextEngineID + */ +public byte [] getContextEngineId(); + +/** + * Sets the contextName. + * See RFC 3411. + * + * A contextName is used to name a context. Each contextName MUST be + * unique within an SNMP entity. + * By default this is "". + * + * @param newContextName The contextName + * @see #Default_ContextName + */ +public void setContextName(String newContextName); + +/** + * Returns the contextName. + * + * @return The contextName + */ +public String getContextName(); + +/** + * Adds a discovery PDU. + * This is for internal use only and should + * NOT be called by the developer. + * + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * @param pdu the discovery PDU + * @return PDU is succesful added + */ +public boolean addDiscoveryPdu(DiscoveryPdu pdu) +throws java.io.IOException, PduException; + + +/** + * Encodes a discovery PDU. + * This is for internal use only and should + * NOT be called by the developer. + * + * This is called by the the PDU itself and is added to the interface to + * cover the different kind of Contexts. + * @return The encoded packet + */ +public byte[] encodeDiscoveryPacket(byte msg_type, int rId, int errstat, + int errind, java.util.Enumeration ve, Object obj) + throws java.io.IOException, EncodingException; + + +/** + * Sets the UsmAgent, needed when this stack is used as authoritative + * SNMP engine. This interface provides authentiation details, like its + * clock and its Engine ID. + * + * @since 4_14 + * @param agent The USM authoritative interface + */ +public void setUsmAgent(UsmAgent agent); + +/** + * Returns the UsmAgent. + * + * @since 4_14 + * @see #setUsmAgent + */ +public UsmAgent getUsmAgent(); + + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Pool.java b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Pool.java new file mode 100644 index 0000000..380d429 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/SnmpContextv3Pool.java @@ -0,0 +1,854 @@ +// NAME +// $RCSfile: SnmpContextv3Pool.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.27 $ +// CREATED +// $Date: 2009/03/05 13:27:41 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import uk.co.westhawk.snmp.pdu.*; +import uk.co.westhawk.snmp.util.*; +import uk.co.westhawk.snmp.event.*; +import java.util.*; + +/** + * This class contains the pool of SNMP v3 contexts. + * This class reuses the existings contexts instead of creating a new + * one every time. + *

    + * Every time a property changes the pool is checked for a SnmpContextv3 + * context that matches all the new properties of this class. If no such + * context exists, a new one is made. + * The PDUs associated with the old context remain associated with the + * old context. + *

    + * + *

    + * A counter indicates the number of times the context is referenced. + * The counter is decreased when destroy() is called. + * When the counter + * reaches zero, the context is released. + *

    + * + *

    + * Note that because the underlying context can change when a property + * is changed and the PDUs remain associated with the old context, all + * properties have to be set BEFORE a PDU is sent. + *

    + * + * @see SnmpContextv3 + * @see SnmpContextPool + * @see SnmpContextv2cPool + * + * @author Birgit Arkesteijn + * @version $Revision: 3.27 $ $Date: 2009/03/05 13:27:41 $ + */ +public class SnmpContextv3Pool implements SnmpContextv3Face +{ + private static final String version_id = + "@(#)$Id: SnmpContextv3Pool.java,v 3.27 2009/03/05 13:27:41 birgita Exp $ Copyright Westhawk Ltd"; + + protected static Hashtable contextPool; + + protected String hostname, socketType, bindAddr; + protected int hostPort; + + protected SnmpContextv3 context = null; + protected String userName = ""; + protected boolean useAuthentication = false; + protected String userAuthenticationPassword = ""; + protected boolean usePrivacy = false; + protected String userPrivacyPassword = ""; + protected int authenticationProtocol = MD5_PROTOCOL; + protected byte [] contextEngineId = new byte[0]; + protected String contextName = Default_ContextName; + protected UsmAgent usmAgent = null; + + protected boolean hasChanged = false; + protected int privacyProtocol = DES_ENCRYPT; + +/** + * Constructor, using the Standard socket. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @see SnmpContextv3#SnmpContextv3(String, int) + */ +public SnmpContextv3Pool(String host, int port) throws java.io.IOException +{ + this(host, port, null, STANDARD_SOCKET); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param typeSocket The type of socket to use. + * + * @see SnmpContextv3#SnmpContextv3(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + */ +public SnmpContextv3Pool(String host, int port, String typeSocket) +throws java.io.IOException +{ + this(host, port, null, typeSocket); +} + +/** + * Constructor. + * Parameter typeSocket should be either STANDARD_SOCKET, TCP_SOCKET or a + * fully qualified classname. + * + * @param host The host to which the PDU will be sent + * @param port The port where the SNMP server will be + * @param bindAddress The local address the server will bind to + * @param typeSocket The type of socket to use. + * + * @see SnmpContextv3#SnmpContextv3(String, int, String) + * @see SnmpContextBasisFace#STANDARD_SOCKET + * @see SnmpContextBasisFace#TCP_SOCKET + * + * @since 4_14 + */ +public SnmpContextv3Pool(String host, int port, String bindAddress, String typeSocket) +throws java.io.IOException +{ + initPools(); + hostname = host; + hostPort = port; + bindAddr = bindAddress; + socketType = typeSocket; + + // No point in creating a context, a lot of the parameters + // are probably going to be set. + //context = getMatchingContext(); +} + +private static synchronized void initPools() +{ + if (contextPool == null) + { + contextPool = new Hashtable(5); + } +} +/** + * Returns the SNMP version of the context. + * + * @return The version + */ +public int getVersion() +{ + return SnmpConstants.SNMP_VERSION_3; +} + +/** + * Returns the host. + * + * @return The host + */ +public String getHost() +{ + return hostname; +} + +/** + * Returns the port number. + * + * @return The port no + */ +public int getPort() +{ + return hostPort; +} + +public String getBindAddress() +{ + return bindAddr; +} + +/** + * Returns the type of socket. + * + * @return The type of socket + */ +public String getTypeSocket() +{ + return socketType; +} + +public String getSendToHostAddress() +{ + String res = null; + if (context != null) + { + res = context.getSendToHostAddress(); + } + return res; +} + +public String getReceivedFromHostAddress() +{ + String res = null; + if (context != null) + { + res = context.getReceivedFromHostAddress(); + } + return res; +} + + +public String getUserName() +{ + return userName; +} + +public void setUserName(String newUserName) +{ + if (newUserName != null && newUserName.equals(userName) == false) + { + userName = newUserName; + hasChanged = true; + } +} + +public boolean isUseAuthentication() +{ + return useAuthentication; +} + +public void setUseAuthentication(boolean newUseAuthentication) +{ + if (newUseAuthentication != useAuthentication) + { + useAuthentication = newUseAuthentication; + hasChanged = true; + } +} + +public String getUserAuthenticationPassword() +{ + return userAuthenticationPassword; +} + +public void setUserAuthenticationPassword(String newUserAuthenticationPd) +{ + if (newUserAuthenticationPd != null + && + newUserAuthenticationPd.equals(userAuthenticationPassword) == false) + { + userAuthenticationPassword = newUserAuthenticationPd; + hasChanged = true; + } +} + +public void setPrivacyProtocol(int protocol) throws IllegalArgumentException +{ + if (protocol == AES_ENCRYPT || protocol == DES_ENCRYPT) + { + if (protocol != privacyProtocol) + { + privacyProtocol = protocol; + hasChanged = true; + } + } + else + { + hasChanged = false; + throw new IllegalArgumentException("Privacy Protocol " + + "should be DES or AES"); + } +} + +public void setAuthenticationProtocol(int protocol) +throws IllegalArgumentException +{ + if (protocol == MD5_PROTOCOL || protocol == SHA1_PROTOCOL) + { + if (protocol != authenticationProtocol) + { + authenticationProtocol = protocol; + hasChanged = true; + } + } + else + { + hasChanged = false; + throw new IllegalArgumentException("Authentication Protocol " + + "should be MD5 or SHA1"); + } +} + + +public int getPrivacyProtocol() +{ + return privacyProtocol; +} + + +public int getAuthenticationProtocol() +{ + return authenticationProtocol; +} + +public boolean isUsePrivacy() +{ + return usePrivacy; +} + +public void setUsePrivacy(boolean newUsePrivacy) +{ + if (newUsePrivacy != usePrivacy) + { + usePrivacy = newUsePrivacy; + hasChanged = true; + } +} + +public String getUserPrivacyPassword() +{ + return userPrivacyPassword; +} + +public void setUserPrivacyPassword(String newUserPrivacyPd) +{ + if (newUserPrivacyPd != null + && + newUserPrivacyPd.equals(userPrivacyPassword) == false) + { + userPrivacyPassword = newUserPrivacyPd; + hasChanged = true; + } +} + + +public void setContextEngineId(byte [] newContextEngineId) +throws IllegalArgumentException +{ + if (newContextEngineId != null) + { + if (newContextEngineId.equals(contextEngineId) == false) + { + contextEngineId = newContextEngineId; + hasChanged = true; + } + } + else + { + hasChanged = false; + throw new IllegalArgumentException("contextEngineId is null"); + } +} + +public byte [] getContextEngineId() +{ + return contextEngineId; +} + +public void setContextName(String newContextName) +{ + if (newContextName != null + && + newContextName.equals(contextName) == false) + { + contextName = newContextName; + hasChanged = true; + } +} + +public String getContextName() +{ + return contextName; +} + + +public void setUsmAgent(UsmAgent newAgent) +{ + if (newAgent != null + && + newAgent != usmAgent) + { + usmAgent = newAgent; + hasChanged = true; + } +} + +public UsmAgent getUsmAgent() +{ + return usmAgent; +} + +public boolean addDiscoveryPdu(DiscoveryPdu pdu) +throws java.io.IOException, PduException, IllegalArgumentException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + return context.addDiscoveryPdu(pdu); +} + +public boolean addPdu(Pdu pdu) +throws java.io.IOException, PduException, IllegalArgumentException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + return context.addPdu(pdu); +} + +public boolean removePdu(int requestId) +{ + boolean res = false; + if (context != null) + { + res = context.removePdu(requestId); + } + return res; +} + +public byte [] encodeDiscoveryPacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws java.io.IOException, EncodingException +{ + byte [] res = null; + if (context != null) + { + res = context.encodeDiscoveryPacket(msg_type, rId, errstat, errind, ve, obj); + } + return res; +} + + +public byte [] encodePacket(byte msg_type, int rId, int errstat, + int errind, Enumeration ve, Object obj) + throws java.io.IOException, EncodingException +{ + byte [] res = null; + if (context != null) + { + res = context.encodePacket(msg_type, rId, errstat, errind, ve, + obj); + } + return res; +} + +public void sendPacket(byte[] packet) +{ + if (context != null) + { + context.sendPacket(packet); + } +} + +/** + * Releases the resources held by this context. This method will + * decrement the reference counter. When the reference counter reaches + * zero the actual context is removed from the pool and destroyed. + */ +public void destroy() +{ + synchronized(contextPool) + { + if (context != null) + { + String hashKey = context.getHashKey(); + + int count = 0; + SnmpContextPoolItem item = (SnmpContextPoolItem) contextPool.get(hashKey); + if (item != null) + { + count = item.getCounter(); + count--; + item.setCounter(count); + } + + if (count <= 0) + { + contextPool.remove(hashKey); + context.destroy(); + } + context = null; + } + } +} + +/** + * Destroys all the contexts in the pool and empties the pool. + * + * @see #destroy() + * @since 4_14 + */ +public void destroyPool() +{ + Hashtable copyOfPool = null; + + synchronized(contextPool) + { + synchronized(contextPool) + { + copyOfPool = (Hashtable) contextPool.clone(); + } + contextPool.clear(); + } + context = null; + hasChanged = true; + + Enumeration keys = copyOfPool.keys(); + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + SnmpContextPoolItem item = (SnmpContextPoolItem) copyOfPool.get(key); + if (item != null) + { + SnmpContextBasisFace cntxt = (SnmpContextBasisFace) item.getContext(); + cntxt.destroy(); + } + } + copyOfPool.clear(); +} + + +public boolean isDestroyed() +{ + boolean isDestroyed = true; + if (context != null) + { + isDestroyed = context.isDestroyed(); + } + return isDestroyed; +} + +/** + * Returns a context from the pool. + * The pre-existing context (if there is any) is destroyed. + * This methods checks for an existing context that matches all our + * properties. If such a context does not exist, a new one is created and + * added to the pool. + * + * @return A context from the pool + * @see #getHashKey + */ +protected SnmpContextv3 getMatchingContext() +throws java.io.IOException, IllegalArgumentException +{ + SnmpContextPoolItem item = null; + SnmpContextv3 newContext = null; + String hashKey = getHashKey(); + + destroy(); + synchronized(contextPool) + { + int count=0; + if (contextPool.containsKey(hashKey)) + { + item = (SnmpContextPoolItem) contextPool.get(hashKey); + newContext = (SnmpContextv3) item.getContext(); + count = item.getCounter(); + } + else + { + newContext = new SnmpContextv3(hostname, hostPort, bindAddr, socketType); + newContext.setContextEngineId(contextEngineId); + newContext.setContextName(contextName); + newContext.setUserName(userName); + newContext.setUseAuthentication(useAuthentication); + newContext.setUserAuthenticationPassword(userAuthenticationPassword); + newContext.setAuthenticationProtocol(authenticationProtocol); + newContext.setUsePrivacy(usePrivacy); + newContext.setUserPrivacyPassword(userPrivacyPassword); + newContext.setUsmAgent(usmAgent); + newContext.setPrivacyProtocol(privacyProtocol); + + item = new SnmpContextPoolItem(newContext); + contextPool.put(hashKey, item); + } + hasChanged = false; + count++; + item.setCounter(count); + } + return newContext; +} + +/** + * Dumps the pool of contexts. This is for debug purposes. + * @param title The title of the dump + */ +public void dumpContexts(String title) +{ + try + { + if (hasChanged == true) + { + context = getMatchingContext(); + } + } + catch (java.io.IOException exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".dumpContexts(): " + exc.getMessage()); + } + } + + System.out.println(title + " " + contextPool.size() + " context(s)"); + Enumeration keys = contextPool.keys(); + int i=0; + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + SnmpContextPoolItem item = (SnmpContextPoolItem) contextPool.get(key); + if (item != null) + { + int count = item.getCounter(); + SnmpContextv3 cntxt = (SnmpContextv3) item.getContext(); + + if (cntxt == context) + { + System.out.println("\tcurrent context: "); + } + System.out.println("\tcontext " + i + ": " + key + ", count: " + count + + ", " + cntxt.toString() + "\n" + + ", " + cntxt.getDebugString()); + i++; + } + } + System.out.println("\thasChanged: " + hasChanged); +} + + +/** + * Returns the hash key. This key is built out of all properties. It + * serves as key for the hashtable of (v3) contexts. + * + * @return The hash key + */ +public String getHashKey() +{ + StringBuffer buffer = new StringBuffer(); + buffer.append(hostname); + buffer.append("_").append(hostPort); + buffer.append("_").append(bindAddr); + buffer.append("_").append(socketType); + buffer.append("_").append(useAuthentication); + buffer.append("_").append(ProtocolNames[authenticationProtocol]); + buffer.append("_").append(ProtocolNames[privacyProtocol]); + buffer.append("_").append(userAuthenticationPassword); + buffer.append("_").append(userName); + buffer.append("_").append(usePrivacy); + buffer.append("_").append(userPrivacyPassword); + buffer.append("_").append(SnmpUtilities.toHexString(contextEngineId)); + buffer.append("_").append(contextName); + buffer.append("_v").append(getVersion()); + + return buffer.toString(); +} + +public void addTrapListener(TrapListener l) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addTrapListener(l); +} + +public void removeTrapListener(TrapListener l) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeTrapListener(l); +} + +public void addTrapListener(TrapListener l, int port) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addTrapListener(l, port); +} + +public void removeTrapListener(TrapListener l, int port) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeTrapListener(l, port); +} + + +public void addTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addTrapListener(l, lcontext); +} + +public void removeTrapListener(TrapListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeTrapListener(l, lcontext); +} + + +public void addRequestPduListener(RequestPduListener l) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addRequestPduListener(l); +} + +public void removeRequestPduListener(RequestPduListener l) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeRequestPduListener(l); +} + +public void addRequestPduListener(RequestPduListener l, int port) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addRequestPduListener(l, port); +} + +public void removeRequestPduListener(RequestPduListener l, int port) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeRequestPduListener(l, port); +} + + +public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.addRequestPduListener(l, lcontext); +} + +public void removeRequestPduListener(RequestPduListener l, ListeningContextPool lcontext) throws java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + context.removeRequestPduListener(l, lcontext); +} + + +public Pdu processIncomingPdu(byte [] message) +throws DecodingException, java.io.IOException +{ + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + + Pdu pdu = null; + pdu = context.processIncomingPdu(message); + return pdu; +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + String res = ""; + try + { + if (hasChanged == true || context == null) + { + context = getMatchingContext(); + } + res = context.toString(); + } + catch (java.io.IOException exc) + { + if (AsnObject.debug > 0) + { + System.out.println(getClass().getName() + ".toString(): " + exc.getMessage()); + } + } + + return res; +} + +/** + * This method is not supported. It will throw a CloneNotSupportedException. + * + * @since 4_14 + */ +public Object clone() throws CloneNotSupportedException +{ + throw new CloneNotSupportedException(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/TimeWindow.java b/src/main/java/uk/co/westhawk/snmp/stack/TimeWindow.java new file mode 100644 index 0000000..42ec7c7 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/TimeWindow.java @@ -0,0 +1,518 @@ +// NAME +// $RCSfile: TimeWindow.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.15 $ +// CREATED +// $Date: 2007/04/12 12:55:28 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.util.*; + +/** + * TimeWindow contains the lookup tables for the engine Id information. + * TimeWindow should be created only once. Use the + * getCurrent() + * method to access any other method, i.e. + *
    + * if (TimeWindow.getCurrent() == null)
    + * {
    + *     TimeWindow timew = new TimeWindow();
    + * }
    + * boolean known = TimeWindow.getCurrent().isSnmpEngineIdKnown(hostaddr, port);
    + * 
    + * + *

    + * This class contains two lookup tables. One that maps the + * host address+port onto the SNMP engine ID and one that keeps the SNMP + * engine ID with the timeline details about this engine. + *

    + * + * @see #getCurrent() + * @author Birgit Arkesteijn + * @version $Revision: 3.15 $ $Date: 2007/04/12 12:55:28 $ + */ +public class TimeWindow +{ + private static final String version_id = + "@(#)$Id: TimeWindow.java,v 3.15 2007/04/12 12:55:28 birgita Exp $ Copyright Westhawk Ltd"; + + /** + * The maximum number of seconds the engine time in the PDU is allowed + * to differ from my estimated engine time. Values 150. + */ + public final static int MaxTimeDifference = 150; + + private static TimeWindow current = null; + + // lookup table hostaddr:port -> engine id + private Hashtable hostLookup; + + // lookup table engine id -> TimeWindowNode + private Hashtable engineLookup; + + private long startTime; + +/** + * Constructor. + */ +public TimeWindow() +{ + if (current == null) + { + current = this; + + hostLookup = new Hashtable(5); + engineLookup = new Hashtable(5); + } +} + +/** + * Returns the current reference to this class. + * TimeWindow should be created only once. Use this method + * to access any other method, i.e. + *
    + * if (TimeWindow.getCurrent() == null)
    + * {
    + *     TimeWindow timew = new TimeWindow();
    + * }
    + * boolean known = TimeWindow.getCurrent().isSnmpEngineIdKnown(hostaddr, port);
    + * 
    + * + * @return the current time window + */ +public static TimeWindow getCurrent() +{ + return current; +} + +/** + * Returns the snmp engine ID. This method will lookup the engine ID + * based on the host address and port. If it the engine ID is not known, null + * will be returned. + * + * @param hostaddr The host address of the engine ID + * @param port The port number of the engine ID + * @return the snmp engine ID + * @see #isSnmpEngineIdKnown(String, int) + */ +public String getSnmpEngineId(String hostaddr, int port) +{ + String key = getKey(hostaddr, port); + String snmpEngineId = (String) hostLookup.get(key); + return snmpEngineId; +} + +/** + * Returns if the snmp engine ID is known. This method will lookup if the + * engine ID belonging to this hostaddr and port is known. + *

    + * When the SNMP engine ID is known, this doesn't necessarily mean that + * the timeline details of this engine ID are known, since it takes a + * second discovery step to find out. + *

    + * + * @param hostaddr The host address of the engine ID + * @param port The port number of the engine ID + * @return whether the snmp engine ID is known + */ +public boolean isSnmpEngineIdKnown(String hostaddr, int port) +{ + String key = getKey(hostaddr, port); + return hostLookup.containsKey(key); +} + +/** + * Sets the SNMP engine ID that belongs to the specified hostaddr and port. + * The old SNMP engine ID (if any) will be overwritten. + * + * @param hostaddr The host address of the engine ID + * @param port The port number of the engine ID + * @param snmpEngineId The engine ID + */ +public void setSnmpEngineId(String hostaddr, int port, String snmpEngineId) +{ + String key = getKey(hostaddr, port); + if (AsnObject.debug > 4) + { + System.out.println(); + System.out.println(getClass().getName() + ".setSnmpEngineId(): hostaddr '" + + hostaddr + "', port '" + port + + "', snmpEngineId '" + snmpEngineId + + "', key '" + key + "'" + ); + } + hostLookup.put(key, snmpEngineId); +} + +/** + * Checks if the engine ID is OK. If there is no engine ID known for + * this hostaddr and port, the specified engine ID is added to the table. + *

    + * If there is + * already an engine ID for this hostaddr and port, the method returns true + * if the specified engine ID is the same as the existing one, and false if + * they differ. In the latter case the engine ID in the table is not updated. + *

    + * + * @param hostaddr The host address of the engine ID + * @param port The port number of the engine ID + * @param snmpEngineId The engine ID + * @return whether the engine ID matches the stored engine ID + * + * @see #setSnmpEngineId(String, int, String) + */ +public boolean isEngineIdOK(String hostaddr, int port, String snmpEngineId) +{ + boolean ok = true; + String key = getKey(hostaddr, port); + if (hostLookup.containsKey(key) == false) + { + setSnmpEngineId(hostaddr, port, snmpEngineId); + } + else + { + String myEngineId = getSnmpEngineId(hostaddr, port); + if (myEngineId.equalsIgnoreCase(snmpEngineId) == false) + { + ok = false; + } + } + + if (AsnObject.debug > 4) + { + System.out.println(); + System.out.println(getClass().getName() + ".isEngineIdOK(): hostaddr '" + + hostaddr + "', port '" + port + + "', snmpEngineId '" + snmpEngineId + + "', ok " + ok); + } + return ok; +} + +/** + * Returns if the timeline details of this snmp engine ID are known. + * + * @param snmpEngineId The engine ID + * @return whether the timeline details are known + */ +public boolean isTimeLineKnown(String snmpEngineId) +{ + return engineLookup.containsKey(snmpEngineId); +} + +/** + * Returns if the time details are outside the time window. + * When a response or report is received, the stack first checks the time + * window before updating it. It always does an update afterwards, even if + * the message was outside the time window! + * + * @param snmpEngineId The SNMP engine ID + * @param bootsA The SNMP engine boots + * @param timeA The SNMP engine time + * @return true if outside or when no details can be found, false if + * inside time window + * @see #updateTimeWindow(String, int, int, boolean) + */ +public boolean isOutsideTimeWindow(String snmpEngineId, int bootsA, + int timeA) +{ + boolean isOut = false; + + TimeWindowNode node = getTimeLine(snmpEngineId); + if (node != null) + { + int bootsL = node.getSnmpEngineBoots(); + int timeL = node.getSnmpEngineTime(); + if (bootsA == TimeWindowNode.maxTime + || + bootsA < bootsL + || + (bootsA == bootsL && timeA < (timeL-MaxTimeDifference))) + { + isOut = true; + } + } + else + { + // We don't have any info, so by definition it is not out. + isOut = false; + } + return isOut; +} + +/** + * Tries to update the time window and returns if succeeded. + * When a response or report is received, first check the time window + * before updating it. + * + *

    + * An update will only occur if the message was authentic + * and the bootsA and timeA meet the requirements. + * New data will be inserted if the (bootsA > 0), irrespectively + * whether the message was authentic or not. + *

    + * + * @param snmpEngineId The SNMP engine ID + * @param bootsA The SNMP engine boots + * @param timeA The SNMP engine time + * @return true if update succeeded, or false when not succeeded or when + * no details could be found. + * @see #isOutsideTimeWindow(String, int, int) + */ +public boolean updateTimeWindow(String snmpEngineId, int bootsA, int +timeA, boolean isAuthentic) +{ + boolean updated = false; + + TimeWindowNode node = getTimeLine(snmpEngineId); + if (node != null) + { + if (isAuthentic) + { + int bootsL = node.getSnmpEngineBoots(); + int latestL = node.getLatestReceivedEngineTime(); + + if (bootsA > bootsL + || + (bootsA == bootsL && timeA > latestL)) + { + synchronized (this) + { + node.setSnmpEngineBoots(bootsA); + node.setSnmpEngineTime(timeA); + updated = true; + } + } + } + } + else if (bootsA > 0 || timeA > 0) + { + // @since 5_2, initially it didn't save when bootsA equals zero + node = new TimeWindowNode(snmpEngineId, bootsA, timeA); + setTimeLine(snmpEngineId, node); + } + + if (AsnObject.debug > 4) + { + System.out.println(); + System.out.println(getClass().getName() + ".updateTimeWindow(): snmpEngineId '" + + snmpEngineId + + "', bootsA " + bootsA + + ", timeA " + timeA + + ", isAuthentic " + isAuthentic + + ", updated " + updated); + } + return updated; +} + +/** + * Clear all timing information for the given engine ID. + * + * This stinks, but occasionally the router's time window will + * slip outside of the acceptable window or will reboot without + * updating its "reboots" parameter. If you care more about + * security than functionality then never ever use this. + * Added on request of Steve A Cochran (steve@more.net). + * @param snmpEngineId The engine to clear + * + * @since 5_2 + */ +public void clearTimeWindow(String snmpEngineId) +{ + if (engineLookup.containsKey(snmpEngineId)) + { + // Remove from engine lookup table + engineLookup.remove(snmpEngineId); + + // Remove any entries in the hostLookup table that point to + // this snmpEngineId + Vector v = new Vector(); + Iterator i = hostLookup.keySet().iterator(); + while (i.hasNext()) + { + String key = (String)(i.next()); + if ((hostLookup.get(key)).equals(snmpEngineId)) + { + v.add(key); + } + } + i = v.iterator(); + while (i.hasNext()) + { + hostLookup.remove(i.next()); + } + } +} + + +/** + * Updates the estimated engine time of all gathered time details. + * It calculates the seconds that passed since the last call and + * updates all time window nodes accordingly. + * + * @see #setTimeLine(String, TimeWindowNode) + * @see #getTimeLine(String) + */ +protected void updateTimeWindows() +{ + if (engineLookup.size() > 0) + { + long now = System.currentTimeMillis(); + long milli = now - startTime; + int sec = (int)(milli / 1000L); + + long lostMillis = milli - (sec * 1000L); + if (lostMillis < 0L) + { + lostMillis = 0L; + } + startTime = now - lostMillis; + + Enumeration nodes = engineLookup.elements(); + while (nodes.hasMoreElements()) + { + TimeWindowNode node = (TimeWindowNode) nodes.nextElement(); + node.incrementSnmpEngineTime(sec); + } + } + else + { + startTime = System.currentTimeMillis(); + } +} + + +/** + * Returns the key to the engine ID lookup table, based on the specified + * host address and port. + * + * @param hostaddr The host address + * @param port The port + * @return the key + */ +protected String getKey(String hostaddr, int port) +{ + return hostaddr + ":" + port; +} + +/** + * Returns the timeline details of the snmp engine ID. + * If there are no matching timeline details for this engine ID, null + * will be returned. + * The timeline details will be updated before the node is retrieved + * from the table. + * + * @param snmpEngineId The engine ID + * @return The timeline details + * @see #updateTimeWindows() + */ +protected TimeWindowNode getTimeLine(String snmpEngineId) +{ + updateTimeWindows(); + TimeWindowNode node = (TimeWindowNode) engineLookup.get(snmpEngineId); + return node; +} + +/** + * Sets the timeline details of the snmp engine ID. + * The timeline details will be updated before the node is put + * in the table. + * + * @param snmpEngineId The engine ID + * @param newNode The added time window node node + * @return The timeline details + * @see #updateTimeWindows() + */ +protected TimeWindowNode setTimeLine(String snmpEngineId, + TimeWindowNode newNode) +{ + updateTimeWindows(); + engineLookup.put(snmpEngineId, newNode); + if (AsnObject.debug > 4) + { + System.out.println(); + System.out.println(getClass().getName() + ".setTimeLine(): snmpEngineId " + + snmpEngineId + + ", node " + newNode); + } + return newNode; +} + +/** + * Returns the string representation. + * + * @since 4_14 + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer(this.getClass().getName()); + buffer.append("["); + + Enumeration enum1 = hostLookup.keys(); + while (enum1.hasMoreElements()) + { + String key = (String) enum1.nextElement(); + String snmpEngineId = (String) hostLookup.get(key); + TimeWindowNode node = (TimeWindowNode) engineLookup.get(snmpEngineId); + buffer.append("\n\t("); + if (node == null) + { + buffer.append("key=").append(key); + buffer.append(", engineId=").append(snmpEngineId); + } + else + { + buffer.append("key=").append(key).append(", "); + buffer.append(node.toString()); + } + buffer.append(") "); + } + + buffer.append("]"); + return buffer.toString(); +} + + + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/TimeWindowNode.java b/src/main/java/uk/co/westhawk/snmp/stack/TimeWindowNode.java new file mode 100644 index 0000000..6484fc8 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/TimeWindowNode.java @@ -0,0 +1,189 @@ +// NAME +// $RCSfile: TimeWindowNode.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2006/01/17 17:43:54 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + */ +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * Node that contains the timeline information of one SNMP Engine ID. + * This entry has to be filled in via Discovery. + * The node will serve as entry in a lookup table. + * + * @author Birgit Arkesteijn + * @version $Revision: 3.10 $ $Date: 2006/01/17 17:43:54 $ + */ +class TimeWindowNode +{ + private static final String version_id = + "@(#)$Id: TimeWindowNode.java,v 3.10 2006/01/17 17:43:54 birgit Exp $ Copyright Westhawk Ltd"; + + public final static int maxTime = 2147483647; // 2^31 -1 + + private String snmpEngineId; + + private int snmpEngineBoots = 0; + private int snmpEngineTime = 0; + private int latestReceivedEngineTime = 0; + +/** + * Constructor. + * + * @param engId The engine ID + */ +public TimeWindowNode(String engId) +{ + this(engId, 0, 0); +} + +/** + * Constructor. + * + * @param engId The engine ID + * @param boots The engine boots + * @param time The engine time + */ +public TimeWindowNode(String engId, int boots, int time) +{ + snmpEngineId = engId; + snmpEngineBoots = boots; + snmpEngineTime = time; + latestReceivedEngineTime = time; +} + + +/** + * Returns the snmp engine ID. + * + * @return the snmp engine ID + */ +public String getSnmpEngineId() +{ + return snmpEngineId; +} + +/** + * Sets the SNMP engine boots + * + * @param newSnmpEngineBoots The SNMP engine boots + */ +public void setSnmpEngineBoots(int newSnmpEngineBoots) +{ + snmpEngineBoots = newSnmpEngineBoots; +} + +/** + * Returns the SNMP engine boots + * + * @return The SNMP engine boots + */ +public int getSnmpEngineBoots() +{ + return snmpEngineBoots; +} + +/** + * Sets the SNMP engine time. It also sets the latest received engine + * time. + * + * @param newSnmpEngineTime The SNMP engine time + */ +public void setSnmpEngineTime(int newSnmpEngineTime) +{ + snmpEngineTime = newSnmpEngineTime; + latestReceivedEngineTime = newSnmpEngineTime; +} + +/** + * Returns the (estimated) SNMP engine time + * + * @return The SNMP engine time + */ +public int getSnmpEngineTime() +{ + return snmpEngineTime; +} + +/** + * Increments the engine time. This mechanisme maintains the loosely + * time synchronisation. + */ +public synchronized void incrementSnmpEngineTime(int incr) +{ + snmpEngineTime += incr; + if (snmpEngineTime > maxTime) + { + snmpEngineBoots++; + snmpEngineTime -= maxTime; + } +} + +/** + * Returns the latest received engine time for an engine ID + * + * @return The latest received engine time + */ +public int getLatestReceivedEngineTime() +{ + return latestReceivedEngineTime; +} + +/** + * Returns a string representation of the object. + * @return The string + */ +public String toString() +{ + StringBuffer buffer = new StringBuffer(this.getClass().getName()); + buffer.append("["); + buffer.append("engineId=").append(snmpEngineId); + buffer.append(", engineBoots=").append(snmpEngineBoots); + buffer.append(", engineTime=").append(snmpEngineTime); + buffer.append(", latestReceivedEngineTime=").append(latestReceivedEngineTime); + buffer.append("]"); + return buffer.toString(); +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/Transmitter.java b/src/main/java/uk/co/westhawk/snmp/stack/Transmitter.java new file mode 100644 index 0000000..d13d25c --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/Transmitter.java @@ -0,0 +1,189 @@ +// NAME +// $RCSfile: Transmitter.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.15 $ +// CREATED +// $Date: 2007/02/05 15:01:20 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1996 - 1998 by Westhawk Ltd (www.westhawk.nl) + * Copyright (C) 1998 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +import java.util.*; + +/** + * Transmitter is a thread that sends PDUs, when done + * it waits. + * + * @author Tim Panton + * @version $Revision: 3.15 $ $Date: 2007/02/05 15:01:20 $ +*/ +class Transmitter extends Object implements Runnable +{ + private static final String version_id = + "@(#)$Id: Transmitter.java,v 3.15 2007/02/05 15:01:20 birgita Exp $ Copyright Westhawk Ltd"; + + Pdu pdu = null; + Thread me; + String myName; + + Transmitter(String name) + { + me = new Thread(this,name); + me.setPriority(me.MIN_PRIORITY); + if (AsnObject.debug > 12) + { + System.out.println("Transmitter(): Made thread " + name); + } + myName =name; + me.start(); + } + + /** + * The method for the Runnable interface. + * + * It will do a sit() untill stand() wakes it up. The Pdu will then + * be transmitted + * + * @see #sit() + * @see #stand() + * @see Pdu#transmit() + */ + public void run() + { + while (me != null) + { + sit(); + synchronized (this) + { + if (pdu != null) + { + pdu.transmit(); + // I will say this only once.... + pdu = null; + } + } + } + } + + /** + * Returns the string representation of the Transmitter. + * + * @return The string of the Transmitter + */ + public String toString() + { + StringBuffer buffer = new StringBuffer(getClass().getName()); + buffer.append("["); + buffer.append("name=").append(myName); + buffer.append("]"); + return buffer.toString(); + } + + synchronized void setPdu(Pdu p) + { + pdu = p; + } + + /** + * This method is the counterpart of stand(). + * + * It does not more than waiting to be notified. + * + * @see #stand() + * @see #run() + */ + synchronized void sit() + { + while ((me != null) && (pdu == null)) + { + try + { + wait(); + } + catch (InterruptedException iw) + { + ; + } + + } + } + + /** + * This method is the counterpart of sit(). + * + * The Pdu will call this method when it is sent. + * This method will notify itself and in the end it is transmitted + * in run. + * + * @see #sit() + * @see #run() + * @see Pdu#send + */ + synchronized void stand() + { + notifyAll(); + } + + /** + * It may be sleeping (as opposed to wait()ing + * so send it a kick. + */ + void interruptMe() + { + // unsafe ? + if (me != null) + { + me.interrupt(); + } + } + + void destroy() + { + me = null; + pdu=null; + stand(); + } +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv1.java b/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv1.java new file mode 100644 index 0000000..d77b0f5 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv1.java @@ -0,0 +1,390 @@ +// NAME +// $RCSfile: TrapPduv1.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.14 $ +// CREATED +// $Date: 2007/10/17 10:44:09 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.util.*; +import java.io.*; +import java.net.*; + +import uk.co.westhawk.snmp.util.*; + +/** + * This class represents the ASN SNMPv1 Trap PDU object. + * See RFC1157-SNMP. + * + *

    + * Note that the SNMPv1 Trap PDU is the only PDU with a different PDU + * format. It has additional fields like enterprise, + * ipAddress, genericTrap, + * specificTrap and timeTicks. + *

    + * + * @see TrapPduv2 + * @author Birgit Arkesteijn + * @version $Revision: 3.14 $ $Date: 2007/10/17 10:44:09 $ + */ +public class TrapPduv1 extends Pdu +{ + private static final String version_id = + "@(#)$Id: TrapPduv1.java,v 3.14 2007/10/17 10:44:09 birgita Exp $ Copyright Westhawk Ltd"; + + private String enterprise; + private byte[] IpAddress; + private int generic_trap; + private int specific_trap; + private long timeTicks; + + private final static String [] genericTrapStrings = + { + "Cold Start", + "Warm Start", + "Link Down", + "Link Up", + "Authentication Failure", + "EGP Neighbor Loss", + "Enterprise Specific", + }; + +/** + * Constructor. + * + * @param con The context (v1) of the TrapPduv1 + * @see SnmpContext + */ +public TrapPduv1(SnmpContext con) +{ + super(con); + setMsgType(AsnObject.TRP_REQ_MSG); + + generic_trap = AsnObject.SNMP_TRAP_WARMSTART; +} + +/** + * Constructor. + * + * @param con The context pool (v1) of the TrapPduv1 + * @see SnmpContext + */ +public TrapPduv1(SnmpContextPool con) +{ + super(con); + setMsgType(AsnObject.TRP_REQ_MSG); + + generic_trap = AsnObject.SNMP_TRAP_WARMSTART; +} + +/** + * Sets the type of object generating the trap. This parameter is based on + * the sysObjectId. + */ +public void setEnterprise(String var) +{ + enterprise = var; +} +/** + * Returns the type of object generating the trap. + */ +public String getEnterprise() +{ + return enterprise; +} + +/** + * Sets the IP Address of the object generating the trap. + */ +public void setIpAddress(byte[] var) +{ + IpAddress = var; +} +/** + * Returns the IP Address of the object generating the trap. + */ +public byte[] getIpAddress() +{ + return IpAddress; +} + +/** + * Sets the generic trap type. By default the warmStart is sent. + * + * @see SnmpConstants#SNMP_TRAP_COLDSTART + * @see SnmpConstants#SNMP_TRAP_WARMSTART + * @see SnmpConstants#SNMP_TRAP_LINKDOWN + * @see SnmpConstants#SNMP_TRAP_LINKUP + * @see SnmpConstants#SNMP_TRAP_AUTHFAIL + * @see SnmpConstants#SNMP_TRAP_EGPNEIGHBORLOSS + * @see SnmpConstants#SNMP_TRAP_ENTERPRISESPECIFIC + */ +public void setGenericTrap(int var) +{ + generic_trap = var; +} +/** + * Returns the generic trap type. + */ +public int getGenericTrap() +{ + return generic_trap; +} +/** + * Returns the string representation of the generic trap. + * + * @return the generic trap string + * @see #getGenericTrap + */ +public String getGenericTrapString() +{ + String trapStr = ""; + if (generic_trap > -1 && generic_trap < genericTrapStrings.length) + { + trapStr = genericTrapStrings[generic_trap]; + } + return trapStr; +} + +/** + * Sets the specific trap code. + */ +public void setSpecificTrap(int var) +{ + specific_trap = var; +} +/** + * Returns the specific trap code. + */ +public int getSpecificTrap() +{ + return specific_trap; +} + +/** + * Sets the sysUpTime of the agent. + * + *

    + * RFC1155-SMI: TimeTicks:
    + * This application-wide type represents a non-negative integer which + * counts the time in hundredths of a second since some epoch. When + * object types are defined in the MIB which use this ASN.1 type, the + * description of the object type identifies the reference epoch. + *

    + */ +public void setTimeTicks(long var) +{ + timeTicks = var; +} +/** + * Returns the sysUpTime of the agent. + * + * @see #setTimeTicks + */ +public long getTimeTicks() +{ + return timeTicks; +} + + +/** + * Sends the TrapPduv1. Since the Trap v1 PDU has a different format + * (sigh), a different encoding message has to be called. + * + * Note that all properties of the context have to be set before this + * point. + */ +public boolean send() throws IOException, PduException +{ + if (added == false) + { + // Moved this statement from the constructor because it + // conflicts with the way the SnmpContextXPool works. + added = context.addPdu(this); + } + Enumeration vbs = reqVarbinds.elements(); + encodedPacket = ((SnmpContext)context).encodePacket(msg_type, enterprise, + IpAddress, generic_trap, specific_trap, timeTicks, vbs); + addToTrans(); + return added; +} + +/** + * The trap PDU does not get a response back. So it should be sent once. + */ +void transmit() +{ + transmit(false); +} + +/** + * Returns the string representation of this object. + * + * @return The string of the PDU + */ +public String toString() +{ + String iPAddressStr = "null"; + if (IpAddress != null) + { + iPAddressStr = (new AsnOctets(IpAddress)).toIpAddress(); + } + StringBuffer buffer = new StringBuffer(getClass().getName()); + buffer.append("["); + buffer.append("context=").append(context); + buffer.append(", reqId=").append(getReqId() ); + buffer.append(", msgType=0x").append(SnmpUtilities.toHex(msg_type)); + buffer.append(", enterprise=").append(enterprise); + buffer.append(", IpAddress=").append(iPAddressStr); + buffer.append(", generic_trap=").append(getGenericTrapString()); + buffer.append(", specific_trap=").append(specific_trap); + buffer.append(", timeTicks=").append(timeTicks); + + buffer.append(", reqVarbinds="); + if (reqVarbinds != null) + { + int sz = reqVarbinds.size(); + buffer.append("["); + for (int i=0; inot expecting a response. + * This method is used in AbstractSnmpContext to help determine whether + * or not to start a thread that listens for a response when sending this + * PDU. + * The default is false. + * + * @return true if a response is expected, false if not. + * @since 4_14 + */ +protected boolean isExpectingResponse() +{ + return false; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv2.java b/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv2.java new file mode 100644 index 0000000..7163c08 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/TrapPduv2.java @@ -0,0 +1,152 @@ +// NAME +// $RCSfile: TrapPduv2.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.11 $ +// CREATED +// $Date: 2006/03/23 14:54:10 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This class represents the ASN SNMP v2c (and higher) Trap PDU object. + * This PDU is not supported in SNMPv1. + * + *

    + * See SNMPv2-PDU;
    + * The variable bindings list contains the following pairs of object + * names and values: +

      +
    • sysUpTime.0 + (SNMPv2-MIB) +
    • +
    • snmpTrapOID.0: part of the trap group in the SNMPv2 MIB + (SNMPv2-MIB) +
    • +
    • If the OBJECTS clause is present in the corresponding + invocation of the macro NOTIFICATION-TYPE, then each corresponding + variable and its value are copied to the variable-bindings field. +
    • +
    • Additional variables may be included at the option of the agent. +
    • +
    + * + *

    + * For SNMPv3: The sender of a trap PDU acts as the authoritative engine. + *

    + * + * @see TrapPduv1 + * @author Birgit Arkesteijn + * @version $Revision: 3.11 $ $Date: 2006/03/23 14:54:10 $ + */ +public class TrapPduv2 extends Pdu +{ + private static final String version_id = + "@(#)$Id: TrapPduv2.java,v 3.11 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * Constructor. + * + * @param con The context (v2c or v3) of the PDU + * @throws IllegalArgumentException if the context version is + * SNMPv1 + */ +public TrapPduv2(SnmpContextBasisFace con) +{ + super(con); + setMsgType(AsnObject.TRPV2_REQ_MSG); + + if (con.getVersion() == SnmpConstants.SNMP_VERSION_1) + { + throw new IllegalArgumentException("A TrapPduv2" + + " can only be sent with an SNMPv2c or SNMPv3 context." + + " NOT with an SNMPv1 context!"); + } +} + +/** + * The trap PDU does not get a response back. So it should be sent once. + * + */ +void transmit() +{ + transmit(false); +} + +/** + * Returns the string representation of this object. + * + * @return The string of the PDU + */ +public String toString() +{ + return super.toString(true); +} + +/** + * Has no meaning, since there is not response. + */ +protected void new_value(int n, varbind res){} + +/** + * Has no meaning, since there is not response. + */ +protected void tell_them(){} + +/** + * Returns that this type of PDU is not expecting a response. + * This method is used in AbstractSnmpContext to help determine whether + * or not to start a thread that listens for a response when sending this + * PDU. + * The default is false. + * + * @return true if a response is expected, false if not. + * @since 4_14 + */ +protected boolean isExpectingResponse() +{ + return false; +} + +} diff --git a/src/main/java/uk/co/westhawk/snmp/stack/UsmAgent.java b/src/main/java/uk/co/westhawk/snmp/stack/UsmAgent.java new file mode 100644 index 0000000..c1ea118 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/UsmAgent.java @@ -0,0 +1,133 @@ +// NAME +// $RCSfile: UsmAgent.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.8 $ +// CREATED +// $Date: 2006/03/23 14:54:10 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This interface provides the SNMPv3 USM (User-Based Security Model) + * authoritative details. + * + *

    + * When the stack is used as authoritative SNMP engine it has to send + * its Engine ID and clock (i.e. Engine Boots and Engine Time) with each + * message. + * The engine who sends a Response, a Trapv2 or a Report is + * authoritative. + *

    + * + *

    + * Since this stack has no means in providing this information, this + * interface has to be implemented by the user. + *

    + * + *

    + * See SNMP-USER-BASED-SM-MIB. + *

    + * @see SnmpContextv3#setUsmAgent + * + * @author Birgit Arkesteijn + * @version $Revision: 3.8 $ $Date: 2006/03/23 14:54:10 $ + */ +public interface UsmAgent +{ + static final String version_id = + "@(#)$Id: UsmAgent.java,v 3.8 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + +/** + * This name ("_myusmagent") is used to create an entry in the TimeWindow + * for the stack to act as authoritative engine. + */ +public String MYFAKEHOSTNAME = "_myusmagent"; + +/** + * Returns the authoritative SNMP Engine ID. + * It uniquely and unambiguously identifies the SNMP engine, within an + * administrative domain. + * + *

    + * The Engine ID is the (case insensitive) string representation of a + * hexadecimal number, without any prefix, for example + * 010000a1d41e4946. + *

    + * @see uk.co.westhawk.snmp.util.SnmpUtilities#toBytes(String) + */ +public String getSnmpEngineId(); + +/** + * Returns the authoritative Engine Boots. + * It is a count of the number of times the SNMP engine has + * re-booted/re-initialized since snmpEngineID was last configured. + */ +public int getSnmpEngineBoots(); + +/** + * Returns the authoritative Engine Time. + * It is the number of seconds since the snmpEngineBoots counter was + * last incremented. + */ +public int getSnmpEngineTime(); + +/** + * Returns the value of the usmStatsUnknownEngineIDs counter. + * The stack needs this when responding to a discovery request. + */ +public long getUsmStatsUnknownEngineIDs(); + +/** + * Returns the value of the usmStatsNotInTimeWindows counter. + * The stack needs this when responding to a discovery request. + */ +public long getUsmStatsNotInTimeWindows(); + +/** + * Sets the current snmp context. + */ +public void setSnmpContext(SnmpContextv3Basis context); +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/usmStatsConstants.java b/src/main/java/uk/co/westhawk/snmp/stack/usmStatsConstants.java new file mode 100644 index 0000000..df9254b --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/usmStatsConstants.java @@ -0,0 +1,138 @@ +// NAME +// $RCSfile: usmStatsConstants.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.7 $ +// CREATED +// $Date: 2006/03/23 14:54:10 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2001 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + * This interface contains the OIDs for the usmStats variables. + * These variables are returned with the SNMPv3 usm security model when + * an error occurs. + * + * They are part of the + * SNMP-USER-BASED-SM-MIB mib. + * + * @see SnmpContextv3 + * + * @author Birgit Arkesteijn + * @version $Revision: 3.7 $ $Date: 2006/03/23 14:54:10 $ + */ +public interface usmStatsConstants +{ + static final String version_id = + "@(#)$Id: usmStatsConstants.java,v 3.7 2006/03/23 14:54:10 birgit Exp $ Copyright Westhawk Ltd"; + + /** + * The total number of packets received by the SNMP engine which + * were dropped because they requested a securityLevel that was + * unknown to the SNMP engine or otherwise unavailable. + */ + public final static String usmStatsUnsupportedSecLevels = "1.3.6.1.6.3.15.1.1.1"; + + /** + * The total number of packets received by the SNMP engine which were + * dropped because they appeared outside of the authoritative SNMP + * engine's window. + */ + public final static String usmStatsNotInTimeWindows = "1.3.6.1.6.3.15.1.1.2"; + + /** + * The total number of packets received by the SNMP engine which + * were dropped because they referenced a user that was not known to + * the SNMP engine. + */ + public final static String usmStatsUnknownUserNames = "1.3.6.1.6.3.15.1.1.3"; + + /** + * The total number of packets received by the SNMP engine which + * were dropped because they referenced an snmpEngineID that was not + * known to the SNMP engine. + */ + public final static String usmStatsUnknownEngineIDs = "1.3.6.1.6.3.15.1.1.4"; + + /** + * The total number of packets received by the SNMP engine which + * were dropped because they didn't contain the expected digest + * value. + */ + public final static String usmStatsWrongDigests = "1.3.6.1.6.3.15.1.1.5"; + + /** + * The total number of packets received by the SNMP engine which + * were dropped because they could not be decrypted. + */ + public final static String usmStatsDecryptionErrors = "1.3.6.1.6.3.15.1.1.6"; + + /** + * The array with all the usmStats dotted OIDs in it. + */ + public final static String [] usmStatsOids= + { + usmStatsUnsupportedSecLevels, + usmStatsNotInTimeWindows, + usmStatsUnknownUserNames, + usmStatsUnknownEngineIDs, + usmStatsWrongDigests, + usmStatsDecryptionErrors + }; + + /** + * The array with all the usmStats verbal OIDs in it. + */ + public final static String [] usmStatsStrings= + { + "usmStatsUnsupportedSecLevels", + "usmStatsNotInTimeWindows", + "usmStatsUnknownUserNames", + "usmStatsUnknownEngineIDs", + "usmStatsWrongDigests", + "usmStatsDecryptionErrors" + }; + +} + diff --git a/src/main/java/uk/co/westhawk/snmp/stack/varbind.java b/src/main/java/uk/co/westhawk/snmp/stack/varbind.java new file mode 100644 index 0000000..4181b49 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/stack/varbind.java @@ -0,0 +1,218 @@ +// NAME +// $RCSfile: varbind.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 3.10 $ +// CREATED +// $Date: 2007/10/17 10:47:47 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 1995, 1996 by West Consulting BV + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +/* + * Copyright (C) 1996 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.stack; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ + +/** + *

    + * This class represents the variable bindings to a PDU. + * A variable consists of a name (an AsnObjectId) and a value (an + * AsnObject) + *

    + * + *

    + * The varbind is usually passed to the Observers of the PDU when + * notifying them. + *

    + * + * @see Pdu#addOid(varbind) + * @see Pdu#addOid(String, AsnObject) + * @author Tim Panton + * @version $Revision: 3.10 $ $Date: 2007/10/17 10:47:47 $ + */ +public class varbind extends Object +{ + private static final String version_id = + "@(#)$Id: varbind.java,v 3.10 2007/10/17 10:47:47 birgita Exp $ Copyright Westhawk Ltd"; + + private AsnObjectId name; + private AsnObject value; + + /** + * Constructor. + * It will clone the varbind given as parameter. + * + * @param var The varbind + */ + public varbind (varbind var) + { + name = var.name; + value = var.value; + } + + /** + * Constructor. + * The name will be set to the Oid, the value will be set to + * AsnNull. This is usually used in Get or GetNext requests. + * + * @param Oid The oid + * @see AsnNull + */ + public varbind(String Oid) + { + this(new AsnObjectId(Oid), new AsnNull()); + } + + /** + * Constructor. + * The name will be set to the Oid, the value will be set to + * AsnNull. This is usually used in Get or GetNext requests. + * + * @param Oid The oid + * @see AsnNull + */ + public varbind(AsnObjectId Oid) + { + this(Oid, new AsnNull()); + } + + /** + * Constructor. + * The name and value will be set. + * This is usually used in Set requests. + * + * @param Oid The oid + * @param val The value for the varbind + */ + public varbind(String Oid, AsnObject val) + { + this(new AsnObjectId(Oid), val); + } + + /** + * Constructor. + * The name and value will be set. + * This is usually used in Set requests. + * + * @param Oid The oid + * @param val The value for the varbind + * @since 4_12 + */ + public varbind(AsnObjectId Oid, AsnObject val) + { + name = Oid; + value = val; + } + + varbind(AsnSequence vb) + throws IllegalArgumentException + { + Object obj = vb.getObj(0); + if (obj instanceof AsnObjectId) + { + name = (AsnObjectId) obj; + value = vb.getObj(1); + } + else + { + String msg = "First object should be AsnObjectId, but is "; + if (obj != null) + { + msg += obj.getClass().getName(); + } + else + { + msg += "null"; + } + throw new IllegalArgumentException(msg); + } + } + + /** + * Returns the oid, this is the name of the varbind. + * + * @return the name as an AsnObjectId + */ + public AsnObjectId getOid() + { + return name; + } + + /** + * Returns the value of the varbind. + * + * @return the value as AsnObject + */ + public AsnObject getValue() + { + return value; + } + + Object setValue(AsnSequence vb) + throws IllegalArgumentException + { + varbind tmp = new varbind(vb); + name = tmp.name; + value = tmp.value; + return value; + } + + /** + * Returns the string representation of the varbind. + * + * @return The string of the varbind + */ + public String toString() + { + return (name.toString() + ": " + value.toString()); + } +} diff --git a/src/main/java/uk/co/westhawk/snmp/util/SnmpUtilities.java b/src/main/java/uk/co/westhawk/snmp/util/SnmpUtilities.java new file mode 100644 index 0000000..6b460f5 --- /dev/null +++ b/src/main/java/uk/co/westhawk/snmp/util/SnmpUtilities.java @@ -0,0 +1,1108 @@ +// NAME +// $RCSfile: SnmpUtilities.java,v $ +// DESCRIPTION +// [given below in javadoc format] +// DELTA +// $Revision: 1.27 $ +// CREATED +// $Date: 2009/03/05 12:57:57 $ +// COPYRIGHT +// Westhawk Ltd +// TO DO +// + +/* + * Copyright (C) 2000 - 2006 by Westhawk Ltd + * www.westhawk.co.uk + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted, provided + * that the above copyright notices appear in all copies and that + * both the copyright notice and this permission notice appear in + * supporting documentation. + * This software is provided "as is" without express or implied + * warranty. + * author Tim Panton + */ + +package uk.co.westhawk.snmp.util; + +/*- + * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲ + * SNMP Java Client + * ჻჻჻჻჻჻ + * Copyright 2023 Sentry Software, Westhawk + * ჻჻჻჻჻჻ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱ + */ +import java.io.*; +import java.util.*; +import uk.co.westhawk.snmp.stack.*; + +import org.bouncycastle.crypto.*; +import org.bouncycastle.crypto.digests.*; +import org.bouncycastle.crypto.params.*; +import org.bouncycastle.crypto.engines.*; + + +/** + * This class contains utilities for key and authentication encoding. + * See SNMP-USER-BASED-SM-MIB. + * + * @author Tim Panton + * @version $Revision: 1.27 $ $Date: 2009/03/05 12:57:57 $ + */ +public class SnmpUtilities extends Object +{ + private static final String version_id = + "@(#)$Id: SnmpUtilities.java,v 1.27 2009/03/05 12:57:57 birgita Exp $ Copyright Westhawk Ltd"; + + final static int ONEMEG = 1048576; + final static int SALT_LENGTH = 8; // in bytes + + private static int salt_count = -1; + private static long asalt; + + +/** + * Returns the String representation of the SNMP version number. + * @param version The version number + * @return The corresponding String. + */ +public static String getSnmpVersionString(int version) +{ + String versionString; + + switch (version) + { + case SnmpConstants.SNMP_VERSION_1: + versionString = "SNMPv1"; + break; + case SnmpConstants.SNMP_VERSION_2c: + versionString = "SNMPv2c"; + break; + case SnmpConstants.SNMP_VERSION_3: + versionString = "SNMPv3"; + break; + default: + versionString = "Unsupported version no " + version; + } + return versionString; +} + +/** + * Converts a hexadecimal ASCII string to a byte array. The method is case + * insensitive, so F7 works as well as f7. The string should have + * the form F7d820 and should omit the '0x'. + * This method is the reverse of toHexString. + * + * @param hexStr The string representing a hexadecimal number + * @return the byte array of hexStr + * @see #toHexString(byte[]) + */ +public static byte [] toBytes(String hexStr) +{ + byte mask = (byte) 0x7F; + byte [] bytes = new byte[0]; + + if (hexStr != null) + { + hexStr = hexStr.toUpperCase(); + int len = hexStr.length(); + bytes = new byte[(len/2)]; + int sPos=0; // position in hexStr + int bPos=0; // position in bytes + while (sPos 255)) + { + throw new IllegalArgumentException("Valid byte values are between 0 and 255." + + "Got " + l); + } + ret = (byte)(l); + return ret; +} + + +/** + * Converts an array of long values to its array of byte values. + * + * @param l The array of longs + * @return The array of bytes + * @throws IllegalArgumentException when one of the longs is not in between 0 and 255. + * + * @see #longToByte(long) + * @since 4_14 + */ +public static byte[] longToByte(long[] l) throws IllegalArgumentException +{ + int len = l.length; + byte [] ret = new byte[len]; + for (int i=0; itoBytes. + * + * @param bytes The byte array + * @return The string representing the byte array + * @see #toBytes(String) + */ +public static String toHexString(byte[] bytes) +{ + String str = ""; + if (bytes != null) + { + int len = bytes.length; + for (int i=0; i> 4) & 0x0F; + val2 = (val & 0x0F); + + return ("" + HEX_DIGIT[val1] + HEX_DIGIT[val2]); +} + +final static char[] HEX_DIGIT = {'0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'}; + + +/** + * Compaires two byte arrays and returns if they are equal. + * + * @param array1 the first byte array + * @param array2 the second byte array + * @return whether they are equal of not. + */ +public static boolean areBytesEqual(byte[] array1, byte[] array2) +{ + boolean same = true; + int len1 = array1.length; + if (len1 == array2.length) + { + int i=0; + while (iSNMP-USER-BASED-SM-MIB. + * + * @param passwKey The password key + * @param engineId The SNMP engine Id + * @see SnmpContextv3#setUserAuthenticationPassword(String) + * @see #passwordToKeyMD5(String) + */ +public static byte [] getLocalizedKeyMD5(byte[] passwKey, String engineId) +{ + byte [] ret = null; + MD5Digest mdc = new MD5Digest(); + mdc.reset(); + + byte [] beid = toBytes(engineId); + if ((beid != null) && (passwKey != null)) + { + // see page 169 of 0-13-021453-1 A Practical Guide to SNMP + mdc.update(passwKey, 0, passwKey.length); + mdc.update(beid, 0, beid.length); + mdc.update(passwKey, 0, passwKey.length); + ret = new byte[mdc.getDigestSize()]; + mdc.doFinal(ret, 0); + } + return ret; +} + +/** + * Converts the user's password and the SNMP Engine Id to the localized key + * using the SHA protocol. + * + * @param passwKey The printable user password + * @param engineId The SNMP engine Id + * @see SnmpContextv3#setUserAuthenticationPassword(String) + */ +public static byte [] getLocalizedKeySHA1(byte[] passwKey, String engineId) +{ + byte [] ret = null; + SHA1Digest mdc = new SHA1Digest(); + mdc.reset(); + + byte [] beid = toBytes(engineId); + if ((beid != null) && (passwKey != null)) + { + // see page 169 of 0-13-021453-1 A Practical Guide to SNMP + mdc.update(passwKey, 0, passwKey.length); + mdc.update(beid, 0, beid.length); + mdc.update(passwKey, 0, passwKey.length); + ret = new byte[mdc.getDigestSize()]; + mdc.doFinal(ret, 0); + } + return ret; +} + + +/** + * Converts the user's password to an authentication key using the SHA1 + * protocol. Note, this is not the same as generating the localized key + * as is + * described in SNMP-USER-BASED-SM-MIB. + * + * @param password The printable user password + * @see SnmpContextv3#setUserAuthenticationPassword(String) + * @see #getLocalizedKeyMD5 + */ +public static byte [] passwordToKeySHA1(String password) +{ + SHA1Digest sha; + byte [] ret =null; + sha = new SHA1Digest(); + byte [] passwordBuf = new byte[64]; + int pl = password.length(); + byte [] pass = new byte[pl]; + + // copy to byte array - stripping off top byte + for (int i=0;i 1) ? new Date() : null ; + + synchronized (sha) + { + while (count < ONEMEG) + { + int cp = 0; + int i=0; + while (i<64) + { + int pim = passwordIndex % pl; + int len = 64 - cp ; + int pr = pl - pim; + if (len > pr) + { + len = pr; + } + System.arraycopy(pass, pim, passwordBuf, cp, len); + i+= len; + cp+=len; + passwordIndex += len; + } + + // need to optimize this..... + sha.update(passwordBuf, 0, passwordBuf.length); + count += 64; + } + // implicit that ONEMEG % 64 == 0 + ret = new byte[sha.getDigestSize()]; + sha.doFinal(ret, 0); + } + + if (AsnObject.debug > 1) + { + Date now = new Date(); + long diff = now.getTime() - then.getTime(); + System.out.println("(Complex) pass to key takes " + diff/1000.0); + } + + return ret; +} +/** + * Converts the user's password to an authentication key using the MD5 + * protocol. Note, this is not the same as generating the localized key + * as is + * described in SNMP-USER-BASED-SM-MIB. + * + * @param password The printable user password + * @see SnmpContextv3#setUserAuthenticationPassword(String) + * @see #getLocalizedKeyMD5 + */ +public static byte [] passwordToKeyMD5(String password) +{ + MD5Digest mdc; + byte [] ret =null; + mdc = new MD5Digest(); + byte [] passwordBuf = new byte[64]; + int pl = password.length(); + byte [] pass = new byte[pl]; + + // copy to byte array - stripping off top byte + for (int i=0;i 1) ? new Date() : null ; + synchronized (mdc) + { + while (count < ONEMEG) + { + int cp = 0; + int i=0; + while (i<64) + { + int pim = passwordIndex % pl; + int len = 64 - cp ; + int pr = pl - pim; + if (len > pr) + { + len = pr; + } + System.arraycopy(pass, pim, passwordBuf, cp, len); + i+= len; + cp+=len; + passwordIndex += len; + } + mdc.update(passwordBuf, 0, passwordBuf.length); + count += 64; + } + // implicit that ONEMEG % 64 == 0 + ret = new byte[mdc.getDigestSize()]; + mdc.doFinal(ret, 0); + } + + if (AsnObject.debug > 1) + { + Date now = new Date(); + long diff = now.getTime() - then.getTime(); + System.out.println("(Complex) pass to key takes "+diff/1000.0); + } + + return ret; +} + + +/** + * Returns the 12 byte MD5 fingerprint. + * @param key The key + * @param message The message + * @see #getFingerPrintSHA1 + */ +public final static byte [] getFingerPrintMD5(byte [] key, byte [] message) +{ + if ((AsnObject.debug > 5) && (key.length != 16)) + { + System.out.println("MD5 key length wrong"); + } + return getFingerPrint(key, message, false); +} + +/** + * Returns the 12 byte SHA1 fingerprint. + * @param key The key + * @param message The message + * @see #getFingerPrintMD5 + */ +public final static byte [] getFingerPrintSHA1(byte [] key, byte [] message) +{ + if ((AsnObject.debug > 5) && (key.length != 20)) + { + System.out.println("SHA1 key length wrong"); + } + return getFingerPrint(key, message, true); +} + + +/** + * Returns the DES salt. + * The "salt" value is generated by concatenating the 32-bit + * snmpEngineBoots value with a 32-bit counter value that the encryption + * engine maintains. This 32-bit counter will be initialised to some + * arbitrary value at boot time. + * + *

    + * See "A Practical Guide to SNMPv3 and Network Management" section 6.8 + * Privacy, p 194. + *

    + * + * @param snmpEngineBoots The (estimated) boots of the authoritative engine + * @return The salt + */ +public final static byte[] getSaltDES(int snmpEngineBoots) +{ + if (salt_count == -1) + { + // initialise the 2nd part of the salt + Random rand = new Random(); + salt_count = rand.nextInt(); + } + byte [] salt = new byte[SALT_LENGTH]; + setBytesFromInt(salt, snmpEngineBoots, 0); + setBytesFromInt(salt, salt_count, SALT_LENGTH/2); + salt_count++; + return salt; +} + +/* + * + * The 64-bit integer is then put into the msgPrivacyParameters field encoded + * as an OCTET STRING of length 8 octets. + * The integer is then modified for the subsequent message. + * We recommend that it is incremented by one until it reaches its + * maximum value, + * at which time it is wrapped. + * An implementation can use any method to vary the value of the local + * 64-bit integer, + * providing the chosen method never generates a duplicate IV for the + * same key. + * + */ + +/** + * Returns the AES salt. + * @return The salt + */ +public static byte[] getSaltAES() +{ + if (asalt == 0) + { + java.security.SecureRandom rand = new java.security.SecureRandom(); + asalt = rand.nextLong(); + } + else + { + asalt ++; + } + byte [] tsalt = new byte[8]; + setBytesFromLong(tsalt, asalt, 0); + return tsalt; +} + +/** + * Returns the DES key. + * The 16-byte secret privacy key is made up of 8 bytes that + * make up the DES key and 8 bytes used as a preinitialisation + * vector. + * + * @param secretPrivacyKey The secret privacy key + * @return The key + */ +public final static byte[] getDESKey(byte[] secretPrivacyKey) +throws PduException +{ + byte [] desKey = new byte[8]; + if (secretPrivacyKey.length < 16) + { + throw new PduException("SnmpUtilities.getDESKey():" + + " secretPrivacyKey is < 16"); + } + System.arraycopy(secretPrivacyKey, 0, desKey, 0, 8); + return desKey; +} + +/** + * Returns the first 128 bits of the localized key Kul are used as the + * AES encryption key. + * @param secretPrivacyKey The secret privacy key + * @return The key + */ +public final static byte[] getAESKey(byte[] secretPrivacyKey) +throws PduException +{ + byte [] aesKey = new byte[16]; + if (secretPrivacyKey.length < 16) + { + throw new PduException("SnmpUtilities.getAESKey():" + + " secretPrivacyKey is < 16"); + } + System.arraycopy(secretPrivacyKey, 0, aesKey, 0, 16); + return aesKey; +} + + +/** + * Returns the DES initial value. + * The 16-byte secret privacy key is made up of 8 bytes that + * make up the DES key and 8 bytes used as a preinitialisation + * vector. + * The initialization vector that is used by the DES algorithm is the + * result of the 8-byte preinitialisation vector XOR-ed with the 8-byte + * "salt". + * + * @param secretPrivacyKey The secret privacy key + * @param salt The salt + * @return The initial value + */ +public final static byte[] getDESInitialValue(byte[] secretPrivacyKey, + byte [] salt) throws PduException +{ + byte [] initV = new byte[8]; + if (secretPrivacyKey.length < 16) + { + throw new PduException("SnmpUtilities.getInitialValue():" + + " secretPrivacyKey is < 16"); + } + + int spk = 8; + for (int i=0; i 0) + { + div ++; + } + int newL = div*8; + byte[] paddedOrig = new byte[newL]; + System.arraycopy(plain, 0, paddedOrig, 0, l); + for (int i=l; i + *
  • + * If the length of the data portion is not a multiple of 8 bytes, the + * message is discarded. + *
  • + *
  • + * The first encrypted text block is decrypted. The decryption result is + * XOR-ed with the initialization vector, and the result is the first + * plaintext block. + *
  • + *
  • + * The rest of the encrypted text blocks are treated similarly. They are + * decrypted, with the results being XOR-ed with the previous encrypted + * text block to obtain the plaintext block. + *
  • + * + * + * @param encryptedText The encrypted text + * @param salt The salt + * @param secretPrivacyKey The secret privacy key + * @return The decrypted bytes + */ +public final static byte[] DESdecrypt(byte[] encryptedText, byte[] salt, + byte[] secretPrivacyKey) throws DecodingException +{ + int l = encryptedText.length; + int div = l / 8; + int mod = l % 8; + if (mod != 0) + { + throw new DecodingException("SnmpUtilities.decrypt():" + + " The encrypted scoped PDU should be a multiple of 8 bytes"); + } + + byte[] desKey = null; + byte[] iv = null; + try + { + desKey = getDESKey(secretPrivacyKey); + iv = getDESInitialValue(secretPrivacyKey, salt); + } + catch (PduException exc) + { + throw new DecodingException(exc.getMessage()); + } + + DESEngine des = new DESEngine(); + DESParameters param = new DESParameters(desKey); + des.init(false, param); + + byte[] plain = new byte[l]; + byte [] in = new byte[8]; + byte [] out = new byte[8]; + byte [] cipherText = iv; + int posPlain = 0; + int posEncr = 0; + for (int b=0; b>> 24) & 0xFF); + ret[j++] = (byte)((v >>> 16) & 0xFF); + ret[j++] = (byte)((v >>> 8) & 0xFF); + ret[j++] = (byte)((v >>> 0) & 0xFF); +} + +final static void setBytesFromLong(byte[] ret, long value, int offs) +{ + long v = value ; + int j = offs; + ret[j++] = (byte)((v >>> 56) & 0xFF); + ret[j++] = (byte)((v >>> 48) & 0xFF); + ret[j++] = (byte)((v >>> 40) & 0xFF); + ret[j++] = (byte)((v >>> 32) & 0xFF); + ret[j++] = (byte)((v >>> 24) & 0xFF); + ret[j++] = (byte)((v >>> 16) & 0xFF); + ret[j++] = (byte)((v >>> 8) & 0xFF); + ret[j++] = (byte)((v >>> 0) & 0xFF); +} + +} diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 149e5aa..39cbcc8 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -1,3 +1,64 @@ -# Documentation +# SNMP Java Client +The SNMP Java client enables you to run SNMP operations, including: -This is the documentation. +- SNMP Client initialization +- Execution of single requests (`Get` and `GetNext`) , as well as multiple request functionalities (`Walk` and `Table`) +- Request execution on remote devices, supporting SNMP v1, v2c, or v3 implementations + +# How to run the SNMP Client inside Java + +Add SNMP in the list of dependencies in your [Maven pom.xml](pom.xml): + +``` + + + + org.sentrysoftware + snmp + ${project.version} + + +``` + +Invoke the SNMP Client: + +``` + public static void main(String[] args) throws Exception { + final String hostname = "my-hostname"; + final int port = 161; + final int version = SnmpClient.SNMP_V2C; + final int[] retryIntervals = { 500, 1000, 2000 }; + final String community = "my-community"; + final String authType = null; // SnmpClient.SNMP_AUTH_MD5; + final String authUsername = null; // "my-username"; + final String authPassword = null; // "my-auth-password"; + final String privacyType = null; // SnmpClient.SNMP_PRIVACY_AES; + final String privacyPassword = null; // "my-privacy-password"; + final String contextName = null; // "my-context-name"; + final byte[] contextID = {}; + + // Initialize the SNMP Client + final SnmpClient snmpClient = new SnmpClient( + hostname, + port, + version, + retryIntervals, + community, + authType, + authUsername, + authPassword, + privacyType, + privacyPassword, + contextName, + contextID + ); + + // MIB 2 DOD OID + final String oid = "1.3.6"; + + // Perform a GetNext operation on the specified MIB 2 OID + final String result = snmpClient.getNext(oid); + + System.out.println("SNMP GetNext Result: " + result); + } +``` diff --git a/src/site/resources/images/sentry-logo-179x75px.png b/src/site/resources/images/sentry-logo-179x75px.png index bdd5fa5..42e53f7 100644 Binary files a/src/site/resources/images/sentry-logo-179x75px.png and b/src/site/resources/images/sentry-logo-179x75px.png differ diff --git a/src/site/site.xml b/src/site/site.xml index b6f8d7f..542653c 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -9,18 +9,22 @@ true - open source,oss + snmp + + images/sentry-logo-179x75px.png + https://sentrysoftware.com + - +