package net.floodlightcontroller.natcs5229; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IListener; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.debugcounter.IDebugCounter; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; import net.floodlightcontroller.core.util.AppCookie; import net.floodlightcontroller.packet.*; import net.floodlightcontroller.routing.IRoutingDecision; import net.floodlightcontroller.routing.Route; import net.floodlightcontroller.util.FlowModUtils; import org.kohsuke.args4j.CmdLineException; import org.projectfloodlight.openflow.protocol.*; import java.io.IOException; import java.util.*; import net.floodlightcontroller.core.IFloodlightProviderService; import java.util.concurrent.ConcurrentSkipListSet; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.match.Match; import org.projectfloodlight.openflow.protocol.match.MatchField; import org.projectfloodlight.openflow.types.*; import org.python.modules._hashlib; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.floodlightcontroller.debugcounter.IDebugCounterService; import net.floodlightcontroller.debugcounter.IDebugCounterService.MetaData; /** * Created by pravein on 28/9/17. */ public class NAT implements IOFMessageListener, IFloodlightModule { protected IFloodlightProviderService floodlightProvider; protected Set macAddresses; private IDebugCounter counterPacketOut; protected static Logger logger; protected IDebugCounterService debugCounterService; HashMap RouterInterfaceMacMap = new HashMap<>(); HashMap IPTransMap = new HashMap<>(); HashMap IPPortMap = new HashMap<>(); HashMap IPMacMap = new HashMap<>(); HashMap ipToRouterInterface = new HashMap<>(); @Override public String getName() { return NAT.class.getName(); } @Override public boolean isCallbackOrderingPrereq(OFType type, String name) { return false; } @Override public boolean isCallbackOrderingPostreq(OFType type, String name) { return false; } // Main Place to Handle PacketIN to perform NAT private Command handlePacketIn(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) { System.out.println("dangal"); System.out.println("choti nikkar"); Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); IPacket pkt = eth.getPayload(); System.out.println("dwdwdwdwdwdwdwdwddwddwdwd"); if (eth.isBroadcast() || eth.isMulticast()) { if (pkt instanceof ARP) { ARP arpRequest = (ARP) eth.getPayload(); String targetProtocolAddress = arpRequest.getTargetProtocolAddress().toString(); IPv4Address srcIP = arpRequest.getSenderProtocolAddress(); System.out.println("Getting arp for (Who has) " + targetProtocolAddress.toString()); String requestor_pno=((pi.getVersion().compareTo(OFVersion.OF_12)) < 0 ? (pi.getInPort().getPortNumber()):(pi.getMatch().get(MatchField.IN_PORT))).toString(); System.out.println("Requestor/Sender (Tell): " + srcIP + "from " + requestor_pno); System.out.println("src MacAddress "+eth.getSourceMACAddress()); System.out.println("targetProtocolAddress "+targetProtocolAddress); System.out.println("lalalla"); //System.out.println("chmpak "+ MacAddress.of(IPMacMap.get(srcIP))); // generate proxy ARP reply // System.out.println("") IPacket arpReply = new Ethernet() .setSourceMACAddress(MacAddress.of(RouterInterfaceMacMap.get(targetProtocolAddress))) .setDestinationMACAddress(eth.getSourceMACAddress()) .setEtherType(EthType.ARP) .setVlanID(eth.getVlanID()) .setPriorityCode(eth.getPriorityCode()) .setPayload( new ARP() .setHardwareType(ARP.HW_TYPE_ETHERNET) .setProtocolType(ARP.PROTO_TYPE_IP) .setHardwareAddressLength((byte) 6) .setProtocolAddressLength((byte) 4) .setOpCode(ARP.OP_REPLY) .setSenderHardwareAddress(MacAddress.of((RouterInterfaceMacMap.get(targetProtocolAddress)))) .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress()) .setTargetHardwareAddress(eth.getSourceMACAddress()) .setTargetProtocolAddress(srcIP)); System.out.println("dushdui"); // push ARP reply out pushPacket(arpReply, sw, OFBufferId.NO_BUFFER, OFPort.ANY, (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)), cntx, true); // pushPacket(arpReply, sw, OFBufferId.NO_BUFFER, IPPortMap.get(), (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)), cntx, true); System.out.println("HO gaya"); } } else { if (pkt instanceof IPv4) { IPv4 ip_pkt = (IPv4) pkt; if (ip_pkt.getProtocol() == IpProtocol.ICMP) { System.out.println("Got an ICMP packtet. Need to pass it on"); /* We got an ICMP packet; get the payload from IPv4 */ ICMP icmp = (ICMP) ip_pkt.getPayload(); System.out.println(icmp); /* Various getters and setters are exposed in ICMP */ Byte code = icmp.getIcmpCode(); Byte type = icmp.getIcmpType(); // TransportPort dstPort = ip_pkt.getDestinationPort(); System.out.println(code +" and "+ type); IPv4Address src_add = ip_pkt.getSourceAddress(); IPv4Address dst_add = ip_pkt.getDestinationAddress(); // src_mac_add = // dst_mac_add = System.out.println(src_add); System.out.println(dst_add); //short flags = icmp.getFlags(); byte bytes[] = pkt.serialize(); int q_id = ((bytes[38] & 0xff) << 8 | bytes[39] & 0xff); System.out.println("q_id" + q_id); int port; if (IPPortMap.containsKey(ip_pkt.getDestinationAddress().toString())) { // check for inbound and outbound if (ip_pkt.getDestinationAddress().toString().matches("10.0.0.11")) { // Perform outbound port = 3; System.out.println("Outbound" +port); // pushPacket(pkt, sw, OFBufferId.NO_BUFFER, OFPort.of(3), // (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : // pi.getMatch().get(MatchField.IN_PORT)), cntx, true); } else { // Perform Inbound if (ip_pkt.getDestinationAddress().toString().matches("192.168.0.10")) { port = 1; System.out.println("in " +port); } else { port = 2; System.out.println("innsx " +port); } } pushPacket(pkt, sw, OFBufferId.NO_BUFFER, OFPort.of(port), (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)), cntx, true); System.out.println("poosed!!!!!!"); } } } } return Command.CONTINUE; } public void pushPacket(IPacket packet, IOFSwitch sw, OFBufferId bufferId, OFPort inPort, OFPort outPort, FloodlightContext cntx, boolean flush) { OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut(); System.out.println("poosing"); // set actions List actions = new ArrayList(); actions.add(sw.getOFFactory().actions().buildOutput().setPort(outPort).setMaxLen(Integer.MAX_VALUE).build()); pob.setActions(actions); // set buffer_id, in_port pob.setBufferId(bufferId); pob.setInPort(inPort); // set data - only if buffer_id == -1 if (pob.getBufferId() == OFBufferId.NO_BUFFER) { if (packet == null) { System.out.println("BufferId is not set and packet data is null. "); // "Cannot send packetOut. " + // "srcSwitch={} inPort={} outPort={}", // new Object[] {sw, inPort, outPort}); return; } byte[] packetData = packet.serialize(); pob.setData(packetData); } counterPacketOut.increment(); sw.write(pob.build()); System.out.println("party all night"); } @Override public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { switch(msg.getType()) { case PACKET_IN: return handlePacketIn(sw, (OFPacketIn)msg, cntx); default: break; } logger.warn("Received unexpected message {}", msg); return Command.CONTINUE; } @Override public Collection> getModuleServices() { return null; } @Override public Map, IFloodlightService> getServiceImpls() { return null; } @Override public Collection> getModuleDependencies() { Collection> l = new ArrayList>(); l.add(IFloodlightProviderService.class); l.add(IDebugCounterService.class); return l; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); macAddresses = new ConcurrentSkipListSet(); logger = LoggerFactory.getLogger(NAT.class); // Use the below HashMaps as per your need debugCounterService = context.getServiceImpl(IDebugCounterService.class); // Router Interface IP to Mac address Mappings RouterInterfaceMacMap.put("10.0.0.1","00:23:10:00:00:01"); RouterInterfaceMacMap.put("192.168.0.1","00:23:10:00:00:02"); RouterInterfaceMacMap.put("192.168.0.2","00:23:10:00:00:03"); // ipToRouterInterface.put("192.168.0.10", "00:00:00:00:00:03"); //ipToRouterInterface.put("192.168.0.20", "00:00:00:00:00:02"); //ipToRouterInterface.put("10.0.0.11", "00:00:00:00:00:03"); // IP to Router Interface mappings IPPortMap.put("192.168.0.10", OFPort.of(1)); IPPortMap.put("192.168.0.20", OFPort.of(2)); IPPortMap.put("10.0.0.11", OFPort.of(3)); //Client/Server ip to Mac mappings IPMacMap.put("192.168.0.10", "00:00:00:00:00:01"); IPMacMap.put("192.168.0.20", "00:00:00:00:00:02"); IPMacMap.put("10.0.0.11", "00:00:00:00:00:03"); } @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); debugCounterService.registerModule(this.getName()); counterPacketOut = debugCounterService.registerCounter(this.getName(), "packet-outs-written", "Packet outs written by the LoadBalancer", MetaData.WARN); } }