package org.freertr.ifc; import org.freertr.addr.addrMac; import org.freertr.pack.packHolder; import org.freertr.util.bits; import org.freertr.enc.encTlv; /** * bridging control protocol (rfc3518) for ppp * * @author matecsaba */ public class ifcPppBrdg extends ifcPppNcp { /** * ppp name */ public final static String pppName = "bcp"; /** * ppp data type */ public final static int pppData = 0x0031; /** * ppp control type */ public final static int pppCtrl = 0x8031; /** * Bridge-Identification */ public final static int optionBriId = 1; /** * Line-Identification */ public final static int optionLinId = 2; /** * MAC-Support */ public final static int optionMacSup = 3; /** * Tinygram-Compression */ public final static int optionTinCmp = 4; /** * LAN-Identification */ public final static int optionLanId = 5; /** * MAC-Address */ public final static int optionMacAdr = 6; /** * Spanning-Tree-Protocol */ public final static int optionSpnTre = 7; /** * IEEE 802 Tagged Frame */ public final static int optionTagd = 8; /** * Management Inline spanning-tree new format */ public final static int optionMgmt = 9; /** * Bridge Control Packet Indicator bpdu enabled */ public final static int optionCtrPkt = 10; /** * update received packet * * @param pck packet */ public static void patchPackRx(packHolder pck) { pck.getSkip(2); } /** * update transmitted packet * * @param pck packet */ public static void patchPackTx(packHolder pck) { pck.msbPutW(0, 0x0001); pck.putSkip(2); pck.merge2beg(); } /** * the constructor * * @param prnt parent */ public ifcPppBrdg(ifcPpp prnt) { parent = prnt; } /** * get name * * @return name */ public String getPPPname() { return pppName; } /** * get control code * * @return code */ public int getPPPctrl() { return pppCtrl; } /** * clear state */ public void clearState() { clearUpperState(false); } /** * got config request * * @param txReq send reply * @return decoded config */ public Object getOneConfig(boolean txReq) { ifcPppBrdgConf cfg = new ifcPppBrdgConf(); if (!txReq) { return cfg; } cfg.tagged = true; cfg.bridgeCtrl = true; cfg.management = true; return cfg; } /** * read options * * @param config configuration * @param tlv tlv * @return false on success, true on error */ public boolean readOption(Object config, encTlv tlv) { ifcPppBrdgConf cfg = (ifcPppBrdgConf) config; switch (tlv.valTyp) { case optionBriId: cfg.bridgeId = bits.msbGetW(tlv.valDat, 0); return false; case optionLinId: cfg.lineId = bits.msbGetW(tlv.valDat, 0); return false; case optionMacSup: cfg.macType = bits.getByte(tlv.valDat, 0); return false; case optionTinCmp: cfg.compress = (tlv.valDat[0] == 1); return false; case optionLanId: return false; case optionMacAdr: cfg.macAddr = new addrMac(); cfg.macAddr.fromBuf(tlv.valDat, 0); return false; case optionSpnTre: cfg.spanTree = bits.getByte(tlv.valDat, 0); return false; case optionTagd: cfg.tagged = (tlv.valDat[0] == 1); return false; case optionMgmt: cfg.management = true; return false; case optionCtrPkt: cfg.bridgeCtrl = true; return false; default: return true; } } /** * write options * * @param pck packet * @param data data */ public void writeOptions(packHolder pck, Object data) { ifcPppBrdgConf dat = (ifcPppBrdgConf) data; encTlv tlv = getTlv(); byte[] buf = new byte[128]; if (dat.bridgeId > 0) { bits.msbPutW(buf, 0, dat.bridgeId); tlv.putBytes(pck, optionBriId, 2, buf); } if (dat.lineId > 0) { bits.msbPutW(buf, 0, dat.lineId); tlv.putBytes(pck, optionLinId, 2, buf); } if (dat.macType > 0) { bits.putByte(buf, 0, dat.macType); tlv.putBytes(pck, optionMacSup, 1, buf); } if (dat.compress) { buf[0] = 1; tlv.putBytes(pck, optionTinCmp, 1, buf); } if (dat.macAddr != null) { dat.macAddr.toBuffer(buf, 0); tlv.putBytes(pck, optionMacAdr, addrMac.size, buf); } if (dat.spanTree > 0) { bits.putByte(buf, 0, dat.spanTree); tlv.putBytes(pck, optionSpnTre, 1, buf); } if (dat.tagged) { buf[0] = 1; tlv.putBytes(pck, optionTagd, 1, buf); } if (dat.management) { tlv.putBytes(pck, optionMgmt, 0, buf); } if (dat.bridgeCtrl) { tlv.putBytes(pck, optionCtrPkt, 0, buf); } } /** * got configure ack * * @param data data * @return false on success, true on error */ public boolean gotConfAck(Object data) { return false; } /** * got configure request * * @param data data * @param rej rejected * @return false on success, true on error */ public Object gotConfReq(Object data, boolean rej) { ifcPppBrdgConf dat = (ifcPppBrdgConf) data; ifcPppBrdgConf res = new ifcPppBrdgConf(); if (dat.compress) { res.compress = true; return res; } if (rej) { return null; } return null; } /** * got configure nak * * @param data data */ public void gotConfNak(Object data) { ifcPppBrdgConf dat = (ifcPppBrdgConf) data; ifcPppBrdgConf cfg = (ifcPppBrdgConf) txReq; if (dat.compress) { cfg.compress = false; } if (dat.bridgeCtrl) { cfg.bridgeCtrl = false; } if (dat.management) { cfg.management = false; } if (dat.tagged) { cfg.tagged = false; } if (dat.bridgeId > 0) { cfg.bridgeId = 0; } if (dat.lineId > 0) { cfg.lineId = 0; } if (dat.macAddr != null) { cfg.macAddr = null; } if (dat.macType > 0) { cfg.macType = 0; } if (dat.spanTree > 0) { cfg.spanTree = 0; } } /** * got configure reject * * @param data data */ public void gotConfRej(Object data) { gotConfNak(data); } /** * got unknown code * * @param pck packet * @param code code * @param id id * @return false on success, true on error */ public boolean gotUnknownCode(packHolder pck, int code, int id) { return true; } } class ifcPppBrdgConf { public int bridgeId = -1; public int lineId = -1; public int macType = -1; public boolean compress; public addrMac macAddr; public int spanTree = -1; public boolean tagged; public boolean management; public boolean bridgeCtrl; public String toString() { return "brid=" + bridgeId + " linid=" + lineId + " macTyp=" + macType + " compress=" + compress + " addr=" + macAddr + " span=" + spanTree + " tag=" + tagged + " mgmt=" + management + " brctr=" + bridgeCtrl; } }