Tuesday, July 29, 2008

Simple Netfilter internet connection sharing

Imagine this, you are in a meeting with your work mates in a hotel which charges unreasonably high internet access fee. You are connected to the Internet via your HSDPA modem. Your mates need to check his mail and to do some administrative stuff on the groupware. You want to share your internet connection and you are using Linux with Iptables(netfilter) installed (whoo..hooo....). Now, how do you do that.
Simple, here is my little bash script, let say inet_share.sh. Customise it as you wish.
#!/bin/bash
CLIENT_BOUND_DEVICE=wlan0
INET_BOUND_DEVICE=ppp0
CLIENT_NETWORK=192.168.5.0/24

echo 0 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -F
/sbin/iptables -F -t nat
/sbin/iptables -F -t mangle

/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD DROP

/sbin/iptables -A FORWARD -i $CLIENT_BOUND_DEVICE -o $INET_BOUND_DEVICE -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i $INET_BOUND_DEVICE -o $CLIENT_BOUND_DEVICE -m state --state RELATED,ESTABLISHED -j ACCEPT

/sbin/iptables -A POSTROUTING -t nat -s $CLIENT_NETWORK -o $INET_BOUND_DEVICE -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward


How to run it?
sudo ./inet_share.sh
Oh, BTW, don't forget to set the DNS on the client machines with the one your machine is currently using. Or, you can install dnsmasq for DNS caching and let your mates' machines use your IP as the DNS server.
Hope, this is also useful.

Monday, July 28, 2008

A Simple SNMP4J usage

For some network administrator, querying an SNMP agent is as simple as executing:
snmpwalk -v2c -c public localhost system
Similarly, Java application developer could do that as well using SNMP4J quite easily. Oh, BTW, don't complain about the length of the code because I don't know how to attach the code to this post..:( Here is the import code snippet
 org.jbs.snmputils.*
 import java.util.List;
 import org.snmp4j.mp.SnmpConstants;
 importorg.snmp4j.smi.*;
and here is how to use it somewhere in your code
    
 Address targetAddress = GenericAddress.parse("udp:localhost/161");
 String comm = "public";
 OID oid = new OID(".1.3.6.1.2.1.1");
 List result = SnmpUtils.walk(SnmpConstants.version2c,targetAddress,comm,oid);
 for (VariableBinding vb: result)
 {
          out.println(vb.getOid()+" : "+vb.getVariable().toString()+"
"); }
Hopefully this might be useful. By the way, the code for SnmpUtils is:
package org.jbs.snmputils;

import java.util.List;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;

/**
 *
 * @author masjoko
 */
public class SnmpUtils {
    public static String get(int version, Address targetaddress, String comm, OID oid)
    {
        if (version==SnmpConstants.version1)
        {
            return SnmpV1Utils.get(targetaddress, comm, oid);
        } else if (version==SnmpConstants.version2c) {
            return SnmpV2cUtils.get(targetaddress, comm, oid);
        } else {
            return null;
        }
    }
    
    public static VariableBinding getNext(int version, Address targetaddress, String comm, OID oid)
    {
        if (version==SnmpConstants.version1)
        {
            return SnmpV1Utils.getNext(targetaddress, comm, oid);
        } else if (version==SnmpConstants.version2c) {
            return SnmpV2cUtils.getNext(targetaddress, comm, oid);
        } else {
            return null;
        }
        
    }
    
    public static List walk(int version, Address address, String comm, OID rootOID)      
    {
        if (version==SnmpConstants.version1)
        {
            return SnmpV1Utils.walk(address, comm, rootOID);
        } else if (version==SnmpConstants.version2c) {
            return SnmpV2cUtils.walk(address, comm, rootOID);
        } else {
            return null;
        }        
    }
}
Which is just a wrapper that calls Snmpv2Utils.
package org.jbs.snmputils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
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.Integer32;
import org.snmp4j.smi.Null;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class SnmpV2cUtils {
    public static String get(Address targetaddress, String comm, OID oid)
    {
        String ret = null;        
        TransportMapping transport;
        try {
            //create transport
            transport = new DefaultUdpTransportMapping();
            CommunityTarget target = new CommunityTarget(); 
            target.setCommunity(new OctetString("public")); 
            target.setAddress(targetaddress); 
            target.setRetries(3); 
            target.setTimeout(2000); 
            target.setVersion(SnmpConstants.version2c); 

            // create the PDU 
            PDU pdu = new PDU(); 
            pdu.setType(PDU.GET);
            //put the oid you want to get
            pdu.add(new VariableBinding(oid)); 
            pdu.setNonRepeaters(0);

            //pdu string
            System.out.println("pdu " + pdu.toString()); 			 
            Snmp snmp = new Snmp(transport);
            snmp.listen();

            // send the PDU 
            ResponseEvent responseEvent = snmp.send(pdu, target); 
            Logger.getLogger(SnmpV2cUtils.class.getName()).log(Level.INFO,responseEvent.toString());            
            // extract the response PDU (could be null if timed out) 
            PDU responsePDU = responseEvent.getResponse(); 
            Logger.getLogger(SnmpV2cUtils.class.getName()).log(Level.INFO,responsePDU.toString());
            Vector vbs = responsePDU.getVariableBindings();
            if (vbs.size()>0)
            {
                VariableBinding vb = (VariableBinding) vbs.get(0);
                ret = vb.getVariable().toString();
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ret;
    }
    
    public static VariableBinding getNext(Address targetaddress, String comm, OID oid)
    {        
        VariableBinding ret = null;
        TransportMapping transport;
        try {
            //create transport
            transport = new DefaultUdpTransportMapping();
            CommunityTarget target = new CommunityTarget(); 
            target.setCommunity(new OctetString("public")); 
            target.setAddress(targetaddress); 
            target.setRetries(3); 
            target.setTimeout(2000); 
            target.setVersion(SnmpConstants.version2c); 

            // create the PDU 
            PDU pdu = new PDU(); 
            pdu.setType(PDU.GETNEXT);
            //put the oid you want to get
            pdu.add(new VariableBinding(oid)); 
            pdu.setNonRepeaters(0);

            //pdu string
            System.out.println("pdu " + pdu.toString()); 			 
            Snmp snmp = new Snmp(transport);
            snmp.listen();

            // send the PDU 
            ResponseEvent responseEvent = snmp.send(pdu, target); 
            Logger.getLogger(SnmpV2cUtils.class.getName()).log(Level.INFO,responseEvent.toString());            
            // extract the response PDU (could be null if timed out) 
            PDU responsePDU = responseEvent.getResponse(); 
            Logger.getLogger(SnmpV2cUtils.class.getName()).log(Level.INFO,responsePDU.toString());
            Vector vbs = responsePDU.getVariableBindings();
            if (vbs.size()>0)
            {
                ret = (VariableBinding) vbs.get(0);                
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ret;
    }

    public static List walk(Address address, String comm, OID rootOID)      
    {
        List ret = new ArrayList();            

        PDU requestPDU = new PDU();
        requestPDU.add(new VariableBinding(rootOID));
        requestPDU.setType(PDU.GETBULK);
        // maximum oid per pdu request
        requestPDU.setMaxRepetitions(5);

        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString(comm));
        target.setAddress(address);
        target.setVersion(SnmpConstants.version2c);        

        try
        {
            TransportMapping transport = new DefaultUdpTransportMapping();
            Snmp snmp = new Snmp(transport);
            transport.listen();

            boolean finished = false;
            int iter = 0;

            while (!finished)
            {
                VariableBinding vb = null;

                ResponseEvent respEvt = snmp.send(requestPDU, target);
                Logger.getLogger(SnmpV2cUtils.class.getName()).log(Level.INFO,"GETBULK iteration number "+iter++);
                PDU responsePDU = respEvt.getResponse();
                
                if (responsePDU != null)
                {                    
                    Vector vbs = responsePDU.getVariableBindings();
                    if (vbs!=null && vbs.size()>0)
                    {
                        for (int i=0; i