Greetings!
I am trying to find a way in Java to programmatically enable/disable a port on a network switch over SNMP. I tried using SNMP4J but couldn't get much help on the mailing list on how to use it. I'm not too concerned what library is used (open source vs commercial) as long as it gets the job done.
The switch I am trying to work with is a Cisco 3750 switch.
Regards,
James
You can use following simple code to enable/disable switch port using snmp4j.
It enables port 1 and disables port 6.
package com.mobinet.snmp;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
/**
*
* #author batbayar
*/
public class SnmpTest {
private String address = "192.168.1.254/161"; // switch address and snmp port
private String writeCommunity = "myCommunityWrite"; // write community name
private Snmp snmp;
private CommunityTarget target;
public SnmpTest() {
try {
TransportMapping transport = new DefaultTcpTransportMapping();
snmp = new Snmp(transport);
Address targetAddress = GenericAddress.parse(address);
target = new CommunityTarget();
target.setCommunity(new OctetString(writeCommunity));
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version2c);
PDU command = new PDU();
command.setType(PDU.SET);
command.add(new VariableBinding(new OID("1.3.6.1.2.1.2.2.1.7.1"), new Integer32(2))); // port 1 down
command.add(new VariableBinding(new OID("1.3.6.1.2.1.2.2.1.7.6"), new Integer32(1))); // port 6 up
ResponseEvent response = snmp.send(command, target);
System.out.println("response: " + response);
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SnmpTest test = new SnmpTest();
}
}
I have had good luck with the Westhawk Java SNMP stack.
For a simple SNMP set, the syntax will look something like this:
public static boolean setOid(String hostAddress, int portNumber, String communityName, String oidToSet, String valueToSet) {
SnmpContextPool context = null;
try {
context = new SnmpContextPool(hostAddress, portNumber, SnmpContextFace.STANDARD_SOCKET);
context.setCommunity(communityName);
SetPdu oneSetPdu = new SetPdu(context);
AsnObject obj = new AsnOctets(valueToSet); // use AsnInteger here if you are setting an integer value
oneSetPdu.addOid(oidToSet, obj);
return oneSetPdu.send();
} catch (Exception e) {
//TODO: Handle exceptions properly
e.printStackTrace();
} finally {
if (context != null) {
context.destroy();
}
}
return false;
}
You could try reading the docs...
A (nearly) complete example for the
SNMP4J API usage is the console tool.
It can be found in the
org.snmp4j.tools.console.SnmpRequest
class.
Related
Trying everyting but it does not work :(
The complete code and example can be found here: https://examples.javacodegeeks.com/core-java/nio/java-nio-ssl-example/
Also you can download the full source (it is only 3 classes) by clicking here: https://examples.javacodegeeks.com/wp-content/uploads/2015/12/NioSSLExample.zip
Thanks for any help!
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
public class NioSSLExample
{
public static void main(String[] args) throws Exception
{
InetSocketAddress address = new InetSocketAddress("www.amazon.com", 443);
Selector selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.connect(address);
channel.configureBlocking(false);
int ops = SelectionKey.OP_CONNECT | SelectionKey.OP_READ;
SelectionKey key = channel.register(selector, ops);
// create the worker threads
final Executor ioWorker = Executors.newSingleThreadExecutor();
final Executor taskWorkers = Executors.newFixedThreadPool(2);
// create the SSLEngine
final SSLEngine engine = SSLContext.getDefault().createSSLEngine();
engine.setUseClientMode(true);
engine.beginHandshake();
final int ioBufferSize = 32 * 1024;
final NioSSLProvider ssl = new NioSSLProvider(key, engine, ioBufferSize, ioWorker, taskWorkers)
{
#Override
public void onFailure(Exception ex)
{
System.out.println("handshake failure");
ex.printStackTrace();
}
#Override
public void onSuccess()
{
System.out.println("handshake success");
SSLSession session = engine.getSession();
try
{
System.out.println("local principal: " + session.getLocalPrincipal());
System.out.println("remote principal: " + session.getPeerPrincipal());
System.out.println("cipher: " + session.getCipherSuite());
}
catch (Exception exc)
{
exc.printStackTrace();
}
//HTTP request
StringBuilder http = new StringBuilder();
http.append("GET / HTTP/1.0\r\n");
http.append("Connection: close\r\n");
http.append("\r\n");
byte[] data = http.toString().getBytes();
ByteBuffer send = ByteBuffer.wrap(data);
this.sendAsync(send);
}
#Override
public void onInput(ByteBuffer decrypted)
{
// HTTP response
byte[] dst = new byte[decrypted.remaining()];
decrypted.get(dst);
String response = new String(dst);
System.out.print(response);
System.out.flush();
}
#Override
public void onClosed()
{
System.out.println("ssl session closed");
}
};
// NIO selector
while (true)
{
key.selector().select();
Iterator keys = key.selector().selectedKeys().iterator();
while (keys.hasNext())
{
keys.next();
keys.remove();
ssl.processInput();
}
}
}
}
http.append("GET / HTTP/1.0\r\n");
http.append("Connection: close\r\n");
http.append("\r\n");
While this is in theory a correct HTTP/1.0 request in practice, most systems today require that a Host header is included. While this is mandatory only with HTTP/1.1 it is needed if an IP address hosts multiple domains:
http.append("GET / HTTP/1.0\r\n");
http.append("Host: www.amazon.com\r\n");
http.append("\r\n");
Also note that the Connection: close is unnecessary since it is implicit with HTTP/1.0 (but not with HTTP/1.1).
Apart from that HTTP is way more complex than this simple request and even this one had its problems as you saw. If you need to implement it for yourself please study the standards instead of making assumptions of how servers react or looking only at a few examples.
I have used the SSHClient class of java to connect to a Juniper router, when entering the console in the putty console it returns the result without problem, but when doing it from the Java code it does not save what is returned by the command, or does not print it, Could you tell me what to do?
I share the ssh class that I am using to guide you in case you encounter any problems:
package com.mycompany;
import static net.sf.expectit.matcher.Matchers.contains;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Shell;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import net.sf.expectit.Expect;
import net.sf.expectit.ExpectBuilder;
public class sshj {
/**
* Launch Commands to Provisioning
*
* #param host
* #param port
* #param user
* #param password
* #param commands
* #param splitBy
* #return result
*/
public static String launchCommands(String host, Integer port, String user, String password, String commands,
String commandsSplitBy, String expectSplitBy, Integer timeoutInSeconds) {
String result = "";
StringBuilder wholeBuffer = new StringBuilder();
SSHClient mSSSHClient = new SSHClient();
mSSSHClient.addHostKeyVerifier(new PromiscuousVerifier());
Session mSession = null;
Shell mShell = null;
Expect mExpect = null;
String[] splitCommands = commands.split(commandsSplitBy);
try {
mSSSHClient.connect(host, port);
mSSSHClient.authPassword(user, password);
mSession = mSSSHClient.startSession();
mShell = mSession.startShell();
mExpect = new ExpectBuilder()
.withOutput(mShell.getOutputStream())
.withInputs(mShell.getInputStream())
.withEchoInput(wholeBuffer)
.withEchoOutput(wholeBuffer)
// .withEchoInput(System.out)
// .withEchoOutput(System.err)
.withExceptionOnFailure()
.withTimeout(timeoutInSeconds, TimeUnit.SECONDS).build();
// When expectSplitBy is equals to ""
if ("".equalsIgnoreCase(expectSplitBy)) {
for (String commandExpect : splitCommands) {
mExpect.sendLine(commandExpect);
}
} else { // When expectSplitBy is not equals to ""
for (String commandExpect : splitCommands) {
String[] commandExpectSplit = commandExpect.split(expectSplitBy);
mExpect.sendLine(commandExpectSplit[0]);
mExpect.expect(contains(commandExpectSplit[1]));
}
}
mShell.close();
mSession.close();
mSSSHClient.disconnect();
result = wholeBuffer.toString();
} catch (IOException e) {
result = wholeBuffer.toString().concat(" The Exception is> ").concat(e.toString());
e.printStackTrace();
try {
mExpect.sendLine("exit");
mShell.close();
mSession.close();
mSSSHClient.disconnect();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return result;
}
}
I found the problem, is that the command sent contains some strange characters at the beginning that look like a blank space, and I could eliminate them and the functionality of the class is executed without problem.
I tagged mule because it's where I'm working with this class, which I know is from a third party, that's why I shared all the code so you could do tests. I am very sorry if you do not find my question clear.
iam new to java programming and my final year project is based on a Rogue Access point detection tool, and i need to how can i obtain SSID from a java code of the exisiting wifi networks?
for eg: say iam in my laptop i need the program to show how many SSIDs are there broadcasting the SSIDS and the names! (through the built in wifi adapter in the laptop).
Thank you.
Java is a High-Level, Platform-Independent programming language. Network settings, and how you control them will depend on your Operating System, and to my knowledge there is no simple way or an API to expose this,but i tried write a code maybe is helpful for you.
Code :
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Electron-Eddine
*/
public class Network {
ArrayList<String> localNetworks = new ArrayList<>();
public static void main(String[] args) throws IOException {
new network.Network().display(new Network().getNetwokrs());
new Network().searchSystemNetwork(new Network().getNetwokrs());
}
public ArrayList<String> getNetwokrs() throws IOException {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "netsh wlan show networks mode=Bssid");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String lineCommand;
String network ;
while (true) {
lineCommand = r.readLine();
if (lineCommand == null) {
break;
} else if (lineCommand.contains("SSID")&&!lineCommand.contains("BSSID")) {
String[] networks = lineCommand.split(":", 2);
network = networks[1];
if (!network.equals(" ")) {
String pureNetworkName = network.trim();
localNetworks.add(pureNetworkName);
} else {
return null;
}
}
}
return localNetworks;
}
private void display(ArrayList<String> networks) {
networks.forEach(network -> {
System.out.println(network);
});
}
private void searchSystemNetwork(ArrayList<String> networks) {
String REQUIRED_NETWORK = "PEER2PEER";
networks.forEach(network -> {
if (network.equals(REQUIRED_NETWORK)) {
System.out.println("Network is availabale");
} else {
}
});
}
void create()
{
// Netsh WLAN export profile key=clear folder="Folder_Path"
}
}
Output :
run:
PEER2PEER
condor PGN522
Ammar_A
Network is availabale
BUILD SUCCESSFUL (total time: 1 second)
I'm not too sure how to go about getting the external IP address of the machine as a computer outside of a network would see it.
My following IPAddress class only gets the local IP address of the machine.
public class IPAddress {
private InetAddress thisIp;
private String thisIpAddress;
private void setIpAdd() {
try {
InetAddress thisIp = InetAddress.getLocalHost();
thisIpAddress = thisIp.getHostAddress().toString();
} catch (Exception e) {
}
}
protected String getIpAddress() {
setIpAdd();
return thisIpAddress;
}
}
I am not sure if you can grab that IP from code that runs on the local machine.
You can however build code that runs on a website, say in JSP, and then use something that returns the IP of where the request came from:
request.getRemoteAddr()
Or simply use already-existing services that do this, then parse the answer from the service to find out the IP.
Use a webservice like AWS and others
import java.net.*;
import java.io.*;
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine(); //you get the IP as a String
System.out.println(ip);
One of the comments by #stivlo deserves to be an answer:
You can use the Amazon service http://checkip.amazonaws.com
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class IpChecker {
public static String getIp() throws Exception {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
return ip;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The truth is: 'you can't' in the sense that you posed the question. NAT happens outside of the protocol. There is no way for your machine's kernel to know how your NAT box is mapping from external to internal IP addresses. Other answers here offer tricks involving methods of talking to outside web sites.
All this are still up and working smoothly! (as of 10 Feb 2022)
http://checkip.amazonaws.com/
https://ipv4.icanhazip.com/
http://myexternalip.com/raw
http://ipecho.net/plain
http://www.trackip.net/ip
http://bot.whatismyipaddress.com (10 Feb 2022)
http://curlmyip.com/ (17 Dec 2016)
Piece of advice: Do not direcly depend only on one of them; try to use one but have a contigency plan considering others! The more you use, the better!
Good luck!
As #Donal Fellows wrote, you have to query the network interface instead of the machine. This code from the javadocs worked for me:
The following example program lists all the network interfaces and their addresses on a machine:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;
public class ListNets {
public static void main(String args[]) throws SocketException {
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets))
displayInterfaceInformation(netint);
}
static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
out.printf("Display name: %s\n", netint.getDisplayName());
out.printf("Name: %s\n", netint.getName());
Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
for (InetAddress inetAddress : Collections.list(inetAddresses)) {
out.printf("InetAddress: %s\n", inetAddress);
}
out.printf("\n");
}
}
The following is sample output from the example program:
Display name: TCP Loopback interface
Name: lo
InetAddress: /127.0.0.1
Display name: Wireless Network Connection
Name: eth0
InetAddress: /192.0.2.0
From docs.oracle.com
Make a HttpURLConnection to some site like www.whatismyip.com and parse that :-)
How about this? It's simple and worked the best for me :)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class IP {
public static void main(String args[]) {
new IP();
}
public IP() {
URL ipAdress;
try {
ipAdress = new URL("http://myexternalip.com/raw");
BufferedReader in = new BufferedReader(new InputStreamReader(ipAdress.openStream()));
String ip = in.readLine();
System.out.println(ip);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
http://jstun.javawi.de/ will do it - provided your gateway device does STUN )most do)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.regex.Pattern;
public class ExternalIPUtil {
private static final Pattern IPV4_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
private static final String[] IPV4_SERVICES = {
"http://checkip.amazonaws.com/",
"https://ipv4.icanhazip.com/",
"http://bot.whatismyipaddress.com/"
// and so on ...
};
public static String get() throws ExecutionException, InterruptedException {
List<Callable<String>> callables = new ArrayList<>();
for (String ipService : IPV4_SERVICES) {
callables.add(() -> get(ipService));
}
ExecutorService executorService = Executors.newCachedThreadPool();
try {
return executorService.invokeAny(callables);
} finally {
executorService.shutdown();
}
}
private static String get(String url) throws IOException {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
String ip = in.readLine();
if (IPV4_PATTERN.matcher(ip).matches()) {
return ip;
} else {
throw new IOException("invalid IPv4 address: " + ip);
}
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("IP: " + get());
}
}
Get from multiple IP services concurrently such as:
http://checkip.amazonaws.com/
https://ipv4.icanhazip.com/
http://bot.whatismyipaddress.com/
and so on ...
and ExecutorService.invokeAny(tasks) return the result of the first successfully thread. Other tasks that have not completed will be cancelled.
It's not that easy since a machine inside a LAN usually doesn't care about the external IP of its router to the internet.. it simply doesn't need it!
I would suggest you to exploit this by opening a site like http://www.whatismyip.com/ and getting the IP number by parsing the html results.. it shouldn't be that hard!
If you are using JAVA based webapp and if you want to grab the client's (One who makes the request via a browser) external ip try deploying the app in a public domain and use request.getRemoteAddr() to read the external IP address.
System.out.println(pageCrawling.getHtmlFromURL("http://ipecho.net/plain"));
An alternative solution is to execute an external command, obviously, this solution limits the portability of the application.
For example, for an application that runs on Windows, a PowerShell command can be executed through jPowershell, as shown in the following code:
public String getMyPublicIp() {
// PowerShell command
String command = "(Invoke-WebRequest ifconfig.me/ip).Content.Trim()";
String powerShellOut = PowerShell.executeSingleCommand(command).getCommandOutput();
// Connection failed
if (powerShellOut.contains("InvalidOperation")) {
powerShellOut = null;
}
return powerShellOut;
}
I need to make an agent in SNMP4J, but the documentation on how to get started is pretty poor. Does anyone have any experience with SNMP4J and could give me an idea on how to get started? Thanks.
You can download the source code for SNMP4JAgent here:
http://www.snmp4j.org/html/download.html
The source code includes a sample agent -- look in the org.snmp4j.agent.example package for all of the related classes.
http://www.snmp4j.org/agent/doc/org/snmp4j/agent/example/SampleAgent.html
One way of getting started would be to create an agent using the example code and then modify it to suit your needs. The JavaDoc describing each of the classes is a bit terse, but it's complete.
Good documentation of SNMPv3 implementation using SNMP4j libraries is really hard to find. There are no working examples of SNMPv3 agents in the official documentation. I wrote a basic SNMP Agent that can connect using SNMPv3 protocol, and perform GET and SET operations on the server.
import java.io.IOException;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthGeneric;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivacyGeneric;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class SNMPV3Agent {
private Address nmsIP;
private String user;
private String securityName;
private String privacyPassword;
private String authorizationPassword;
private AuthGeneric authProtocol;
private PrivacyGeneric privacyProtocol;
private String protocol;
private long timeOut = 1000L;
private int noOfRetries = 2;
private Snmp snmp;
private UserTarget target;
SNMPV3Agent(String ip, String protocol, int snmpPort, String username,
String securityName, String privacyPassword, String authPassowrd,
AuthGeneric authProtocol, PrivacyGeneric privacyProtocol) {
nmsIP = GenericAddress.parse(protocol + ":" + ip + "/" + snmpPort);
System.out.println("NMS IP set : " + nmsIP.toString());
this.protocol = protocol;
this.user = username;
this.securityName = securityName;
this.privacyPassword = privacyPassword;
this.authorizationPassword = authPassowrd;
this.authProtocol = authProtocol;
this.privacyProtocol = privacyProtocol;
}
public static void main(String[] args) {
SNMPV3Agent agent = new SNMPV3Agent("nms/server-ip", "udp", 162,
"abhinav", "abhinav", "myprivpass", "myauthpass",
new AuthSHA(), new PrivAES128());
try {
agent.startAgent();
ResponseEvent response = agent
.snmpGetOperation(SnmpConstants.sysName);
System.out.println(response.getResponse());
// Similarly you can perform set operation.
} catch (IOException e) {
e.printStackTrace();
}
}
public void startAgent() throws IOException {
if (snmp == null) {
TransportMapping<? extends TransportIpAddress> transport = null;
if (protocol.equalsIgnoreCase("udp")) {
System.out.println("UDP Protocol selected.");
transport = new DefaultUdpTransportMapping();
} else {
System.out.println("TCP Protocol selected.");
transport = new DefaultTcpTransportMapping();
}
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();
snmp.getUSM().addUser(
new OctetString(user),
new UsmUser(new OctetString(securityName), authProtocol
.getID(), new OctetString(authorizationPassword),
privacyProtocol.getID(), new OctetString(
privacyPassword)));
target = createUserTarget();
}
}
public ResponseEvent snmpSetOperation(VariableBinding[] vars)
throws IOException {
PDU setPdu = new ScopedPDU();
for (VariableBinding variableBinding : vars) {
setPdu.add(variableBinding);
}
return snmp.send(setPdu, target);
}
public ResponseEvent snmpGetOperation(OID oid) throws IOException {
PDU getPdu = new ScopedPDU();
getPdu.add(new VariableBinding(oid));
return snmp.get(getPdu, target);
}
private UserTarget createUserTarget() {
UserTarget target = new UserTarget();
target.setAddress(nmsIP);
target.setRetries(noOfRetries);
target.setTimeout(timeOut);
target.setVersion(3);
target.setSecurityLevel(3);
target.setSecurityName(new OctetString(securityName));
return target;
}
public long getTimeOut() {
return timeOut;
}
public void setTimeOut(long timeOut) {
this.timeOut = timeOut;
}
public int getNoOfRetries() {
return noOfRetries;
}
public void setNoOfRetries(int noOfRetries) {
this.noOfRetries = noOfRetries;
}
}
Adding other operations such as GETBulk will be relatively easy once you understand how GET and SET works. Let me know if you need more clarifications in the comments.
Here is a great link that describes the snmp class which is the core of snmp4j
http://www.snmp4j.org/doc/org/snmp4j/package-summary.html
Also take a look at the SnmpRequest.java for a quick example