package org.freertr.clnt; import org.freertr.addr.addrEmpty; import org.freertr.addr.addrIP; import org.freertr.addr.addrType; import org.freertr.ifc.ifcDn; import org.freertr.ifc.ifcEther; import org.freertr.ifc.ifcNull; import org.freertr.ifc.ifcUp; import org.freertr.ip.ipFwdIface; import org.freertr.pack.packHolder; import org.freertr.prt.prtGenConn; import org.freertr.prt.prtServP; import org.freertr.prt.prtUdp; import org.freertr.util.bits; import org.freertr.util.counter; import org.freertr.util.logger; import org.freertr.util.state; /** * locator id separation protocol (rfc6830) client * * @author matecsaba */ public class clntLisp implements Comparable, Runnable, prtServP, ifcDn { /** * create instance */ public clntLisp() { } /** * port number */ public final static int portNum = 4341; /** * upper layer */ public ifcUp upper = new ifcNull(); /** * target of tunnel */ public addrIP target; /** * remote port number */ public int prtR; /** * local port number */ public int prtL; /** * udp to use */ public prtUdp udp; /** * source interface */ public ipFwdIface fwdIfc = null; /** * sending ttl value, -1 means maps out */ public int sendingTTL = 255; /** * sending tos value, -1 means maps out */ public int sendingTOS = -1; /** * sending df value, -1 means maps out */ public int sendingDFN = -1; /** * sending flow value, -1 means maps out */ public int sendingFLW = -1; /** * counter */ public counter cntr = new counter(); private prtGenConn conn; private boolean working = true; public String toString() { return "lisp to " + target; } public int compareTo(clntLisp o) { return target.compareTo(o.target); } /** * get hw address * * @return hw address */ public addrType getHwAddr() { return new addrEmpty(); } /** * set filter * * @param promisc promiscous mode */ public void setFilter(boolean promisc) { } /** * get state * * @return state */ public state.states getState() { return state.states.up; } /** * close interface */ public void closeDn() { clearState(); } /** * flap interface */ public void flapped() { clearState(); } /** * set upper layer * * @param server upper layer */ public void setUpper(ifcUp server) { upper = server; upper.setParent(this); } /** * get counter * * @return counter */ public counter getCounter() { return cntr; } /** * get mtu size * * @return mtu size */ public int getMTUsize() { return 1400; } /** * get bandwidth * * @return bandwidth */ public long getBandwidth() { return 4000000; } /** * send packet * * @param pck packet */ public void sendPack(packHolder pck) { if (conn == null) { return; } cntr.tx(pck); pck.merge2beg(); if (ifcEther.stripEtherType(pck)) { cntr.drop(pck, counter.reasons.badProto); return; } pck.msbPutD(0, 0); // flags + nonce pck.msbPutD(4, 0); // istance + lsb pck.putSkip(8); pck.merge2beg(); pck.putDefaults(); conn.send2net(pck); } /** * start connection */ public void workStart() { new Thread(this).start(); } /** * stop connection */ public void workStop() { working = false; clearState(); } public void run() { for (;;) { if (!working) { break; } try { clearState(); workDoer(); } catch (Exception e) { logger.traceback(e); } clearState(); bits.sleep(1000); } } private void workDoer() { if (prtR == 0) { prtR = portNum; } if (prtL == 0) { prtL = prtR; } conn = udp.packetConnect(this, fwdIfc, prtL, target, prtR, "lisp", -1, null, -1, -1); if (conn == null) { return; } conn.timeout = 120000; conn.sendTOS = sendingTOS; conn.sendDFN = sendingDFN; conn.sendFLW = sendingFLW; conn.sendTTL = sendingTTL; for (;;) { bits.sleep(1000); if (!working) { return; } if (conn.txBytesFree() < 0) { return; } } } private void clearState() { if (conn != null) { conn.setClosing(); } } /** * close interface * * @param ifc interface */ public void closedInterface(ipFwdIface ifc) { } /** * accept connection * * @param id connection * @return false on success, true on error */ public boolean datagramAccept(prtGenConn id) { return true; } /** * connection ready * * @param id connection */ public void datagramReady(prtGenConn id) { } /** * close connection * * @param id connection */ public void datagramClosed(prtGenConn id) { } /** * work connection * * @param id connection */ public void datagramWork(prtGenConn id) { } /** * received error * * @param id connection * @param pck packet * @param rtr reporting router * @param err error happened * @param lab error label * @return false on success, true on error */ public boolean datagramError(prtGenConn id, packHolder pck, addrIP rtr, counter.reasons err, int lab) { return false; } /** * notified that state changed * * @param id id number to reference connection * @param stat state * @return return false if successful, true if error happened */ public boolean datagramState(prtGenConn id, state.states stat) { return false; } /** * received packet * * @param id connection * @param pck packet * @return false on success, true on error */ public boolean datagramRecv(prtGenConn id, packHolder pck) { pck.getSkip(8); cntr.rx(pck); int i = ifcEther.guessEtherType(pck); if (i < 0) { cntr.drop(pck, counter.reasons.badVer); return true; } pck.msbPutW(0, i); i = pck.headSize(); pck.putSkip(2); pck.mergeHeader(-1, i); upper.recvPack(pck); return false; } }