package org.freertr.ifc; import org.freertr.addr.addrIPv4; import org.freertr.pack.packHolder; import org.freertr.util.bits; import org.freertr.enc.encTlv; /** * ipv4 control protocol (rfc1332) for ppp * * @author matecsaba */ public class ifcPppIp4 extends ifcPppNcp { /** * ppp name */ public final static String pppName = "ipv4cp"; /** * ppp data type */ public final static int pppData = 0x0021; /** * ppp control type */ public final static int pppCtrl = 0x8021; /** * my address, null=negotiated */ public addrIPv4 locAddrCur; /** * peer address, null=negotiated */ public addrIPv4 remAddrCur; /** * dns1 address */ public addrIPv4 dns1addrCur; /** * dns2 address */ public addrIPv4 dns2addrCur; /** * local address required */ public boolean locAddrReq; /** * IP-Addresses */ public final static int optionAddres = 1; /** * IP-Compression-Protocol */ public final static int optionCompress = 2; /** * IP-Address */ public final static int optionAddr = 3; /** * Mobile-Node-Home-Address */ public final static int optionMobil = 4; /** * Primary-DNS-Address */ public final static int optionDns1 = 129; /** * Secondary-DNS-Address */ public final static int optionDns2 = 131; /** * Primary-NBNS-Address */ public final static int optionNbns1 = 130; /** * Secondary-NBNS-Address */ public final static int optionNbns2 = 132; /** * the constructor * * @param prnt parent */ public ifcPppIp4(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() { if (parent.locAddrCfg == null) { locAddrCur = null; } else { locAddrCur = parent.locAddrCfg.copyBytes(); } if (parent.remAddrCfg == null) { remAddrCur = null; } else { remAddrCur = parent.remAddrCfg.copyBytes(); } if (parent.dns1addrCfg == null) { dns1addrCur = null; } else { dns1addrCur = parent.dns1addrCfg.copyBytes(); } if (parent.dns2addrCfg == null) { dns2addrCur = null; } else { dns2addrCur = parent.dns2addrCfg.copyBytes(); } locAddrReq = parent.locAddrReq; clearUpperState(false); } /** * get one config * * @param txReq send reply * @return data */ public Object getOneConfig(boolean txReq) { ifcPppIp4conf cfg = new ifcPppIp4conf(); if (!txReq) { return cfg; } if (locAddrCur != null) { cfg.addr = locAddrCur.copyBytes(); } if (dns1addrCur != null) { cfg.dns1 = dns1addrCur.copyBytes(); } if (dns2addrCur != null) { cfg.dns2 = dns2addrCur.copyBytes(); } return cfg; } /** * read options * * @param config config * @param tlv tlv * @return false on success, true on error */ public boolean readOption(Object config, encTlv tlv) { ifcPppIp4conf cfg = (ifcPppIp4conf) config; switch (tlv.valTyp) { case optionAddres: cfg.addr = new addrIPv4(); cfg.addr.fromBuf(tlv.valDat, 0); return false; case optionAddr: cfg.addr = new addrIPv4(); cfg.addr.fromBuf(tlv.valDat, 0); return false; case optionDns1: cfg.dns1 = new addrIPv4(); cfg.dns1.fromBuf(tlv.valDat, 0); return false; case optionDns2: cfg.dns2 = new addrIPv4(); cfg.dns2.fromBuf(tlv.valDat, 0); return false; case optionNbns1: cfg.nbns1 = new addrIPv4(); cfg.nbns1.fromBuf(tlv.valDat, 0); return false; case optionNbns2: cfg.nbns2 = new addrIPv4(); cfg.nbns2.fromBuf(tlv.valDat, 0); return false; case optionCompress: cfg.compress = bits.msbGetW(tlv.valDat, 0); return false; default: return true; } } /** * write options * * @param pck packet * @param data data */ public void writeOptions(packHolder pck, Object data) { ifcPppIp4conf dat = (ifcPppIp4conf) data; encTlv tlv = getTlv(); byte[] buf = new byte[128]; if (dat.compress > 0) { bits.msbPutW(buf, 0, dat.compress); tlv.putBytes(pck, optionCompress, 2, buf); } if (dat.addr != null) { dat.addr.toBuffer(buf, 0); tlv.putBytes(pck, optionAddr, addrIPv4.size, buf); } if (dat.dns1 != null) { dat.dns1.toBuffer(buf, 0); tlv.putBytes(pck, optionDns1, addrIPv4.size, buf); } if (dat.dns2 != null) { dat.dns2.toBuffer(buf, 0); tlv.putBytes(pck, optionDns2, addrIPv4.size, buf); } if (dat.nbns1 != null) { dat.nbns1.toBuffer(buf, 0); tlv.putBytes(pck, optionNbns1, addrIPv4.size, buf); } if (dat.nbns2 != null) { dat.nbns2.toBuffer(buf, 0); tlv.putBytes(pck, optionNbns2, addrIPv4.size, buf); } } /** * got configure ack * * @param data data * @return false on success, true on error */ public boolean gotConfAck(Object data) { ifcPppIp4conf dat = (ifcPppIp4conf) data; if (locAddrReq) { if (dat.addr == null) { return true; } if (dat.addr.isEmpty()) { return true; } } return false; } /** * got configure request * * @param data data * @param rej rejected * @return config */ public Object gotConfReq(Object data, boolean rej) { boolean val = false; ifcPppIp4conf dat = (ifcPppIp4conf) data; ifcPppIp4conf res = new ifcPppIp4conf(); if (dat.compress > 0) { res.compress = dat.compress; val = true; } if (rej) { if (val) { return res; } else { return null; } } if (dat.addr != null) { if (parent.remAddrCfg != null) { if (dat.addr.compareTo(parent.remAddrCfg) != 0) { res.addr = remAddrCur.copyBytes(); val = true; } } if (remAddrCur == null) { remAddrCur = dat.addr; } else { if (dat.addr.compareTo(remAddrCur) != 0) { res.addr = remAddrCur.copyBytes(); val = true; } } } if (dat.dns1 != null) { if (dat.dns1.isEmpty() && (parent.dns1addrCfg != null)) { res.dns1 = parent.dns1addrCfg.copyBytes(); val = true; } } if (dat.dns2 != null) { if (dat.dns2.isEmpty() && (parent.dns2addrCfg != null)) { res.dns2 = parent.dns2addrCfg.copyBytes(); val = true; } } if (val) { return res; } else { return null; } } /** * got configure nak * * @param data data */ public void gotConfNak(Object data) { ifcPppIp4conf dat = (ifcPppIp4conf) data; ifcPppIp4conf cfg = (ifcPppIp4conf) txReq; if (dat.compress > 0) { cfg.compress = 0; } if ((dat.addr != null) && (locAddrCur != null)) { locAddrCur = dat.addr; cfg.addr = dat.addr; } if ((dat.dns1 != null) && (dns1addrCur != null)) { dns1addrCur = dat.dns1; cfg.dns1 = dat.dns1; } if ((dat.dns2 != null) && (dns2addrCur != null)) { dns2addrCur = dat.dns2; cfg.dns2 = dat.dns2; } if ((dat.nbns1 != null) && (dns1addrCur != null)) { cfg.nbns1 = dat.nbns1; } if ((dat.nbns2 != null) && (dns2addrCur != null)) { cfg.nbns2 = dat.nbns2; } } /** * got configure reject * * @param data data */ public void gotConfRej(Object data) { ifcPppIp4conf dat = (ifcPppIp4conf) data; ifcPppIp4conf cfg = (ifcPppIp4conf) txReq; if (dat.compress > 0) { cfg.compress = 0; } if (dat.addr != null) { cfg.addr = null; } if (dat.dns1 != null) { cfg.dns1 = null; } if (dat.dns2 != null) { cfg.dns2 = null; } if (dat.nbns1 != null) { cfg.nbns1 = null; } if (dat.nbns2 != null) { cfg.nbns2 = null; } } /** * 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 ifcPppIp4conf { public addrIPv4 addr = null; public addrIPv4 dns1 = null; public addrIPv4 dns2 = null; public addrIPv4 nbns1 = null; public addrIPv4 nbns2 = null; public int compress = -1; public String toString() { return "addr=" + addr + " dns1=" + dns1 + " dns2=" + dns2 + " compress=" + compress + " nbns1=" + nbns1 + " nbns2=" + nbns2; } }