⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcpoption.java

📁 DHCP 的JAVA实现
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	 * DHO_STDA_SERVER(76)
	 * DHO_NDS_SERVERS(85)
     * </pre>
     * 
     * @param code the option code.
     * @param val the value array
     * @throws IllegalArgumentException the option code is not in the list above.
     */
    public static DHCPOption newOptionAsInetAddresses(byte code, InetAddress[] val) {
    	if (!isOptionAsInetAddrs(code)) {
            throw new IllegalArgumentException("DHCP option type ("+code+") is not InetAddresses");
        }
        return new DHCPOption(code, inetAddresses2Bytes(val));
    }

    /**
     * Creates a DHCP Option as String format.
     * 
     * <p>This method is only allowed for the following option codes:
     * <pre>
	 * DHO_HOST_NAME(12)
	 * DHO_MERIT_DUMP(14)
	 * DHO_DOMAIN_NAME(15)
	 * DHO_ROOT_PATH(17)
	 * DHO_EXTENSIONS_PATH(18)
	 * DHO_NETBIOS_SCOPE(47)
	 * DHO_DHCP_MESSAGE(56)
	 * DHO_VENDOR_CLASS_IDENTIFIER(60)
	 * DHO_NWIP_DOMAIN_NAME(62)
	 * DHO_NIS_DOMAIN(64)
	 * DHO_NIS_SERVER(65)
	 * DHO_TFTP_SERVER(66)
	 * DHO_BOOTFILE(67)
	 * DHO_NDS_TREE_NAME(86)
	 * DHO_USER_AUTHENTICATION_PROTOCOL(98)
     * </pre>
     * 
     * @param code the option code.
     * @param val the value
     * @throws IllegalArgumentException the option code is not in the list above.
     */
    public static DHCPOption newOptionAsString(byte code, String val) {
    	if (!isOptionAsString(code)) {
            throw new IllegalArgumentException("DHCP option type ("+code+") is not string");
        }
    	return new DHCPOption(code, DHCPPacket.stringToBytes(val));
    }

	/**
	 * Get the option value based on the context, i.e. the client's request.
	 * 
	 * <p>This should be the only method used with this class to get relevant values.
	 * 
	 * @param request the client's DHCP requets
	 * @return the value of the specific option in the client request
	 * @throws NullPointerException if <tt>request</tt> is <tt>null</tt>.
	 */
	public DHCPOption applyOption(DHCPPacket request) {
		if (request == null) {
			throw new NullPointerException("request is null");
		}
		if (this.mirror) {
			DHCPOption res = request.getOption(this.getCode());
			return (res != null ? res : this);	// return res or this
		} else {
			return this;
		}
	}
	
    /**
     * Appends to this string builder a detailed string representation of the DHCP datagram.
     *
     * <p>This multi-line string details: the static, options and padding parts
     * of the object. This is useful for debugging, but not efficient.
     *
     * @param buffer the string builder the string representation of this object should be appended.
     */
    public void append(StringBuilder buffer) {
        // check for readable option name
        if (_DHO_NAMES.containsKey(this.code)) {
        	buffer.append(_DHO_NAMES.get(this.code));
        }
        buffer.append('(')
              .append(unsignedByte(this.code))
              .append(")=");
        
        if (this.mirror) {
        	buffer.append("<mirror>");
        }

        // check for value printing
        if (this.value == null) {
        	buffer.append("<null>");
        } else if (this.code == DHO_DHCP_MESSAGE_TYPE) {
        	Byte cmd = this.getValueAsByte();
        	if (_DHCP_CODES.containsKey(cmd)) {
        		buffer.append(_DHCP_CODES.get(cmd));
        	} else {
        		buffer.append(cmd);
        	}
        } else if (this.code == DHO_USER_CLASS) {
        	buffer.append(userClassToString(this.value));
        } else if (this.code == DHO_DHCP_AGENT_OPTIONS) {
        	buffer.append(agentOptionsToString(this.value));
        } else if (_DHO_FORMATS.containsKey(this.code)) {
        	// formatted output
        	try {	// catch malformed values
        		switch (_DHO_FORMATS.get(this.code)) {
                    case INET:
                        DHCPPacket.appendHostAddress(buffer, this.getValueAsInetAddr());
                        break;
                    case INETS:
                        for (InetAddress addr : this.getValueAsInetAddrs()) {
                            DHCPPacket.appendHostAddress(buffer, addr);
                            buffer.append(' ');
                        }
                        break;
                    case INT:
                        buffer.append(this.getValueAsInt());
                        break;
                    case SHORT:
                        buffer.append(this.getValueAsShort());
                        break;
                    case SHORTS:
                        for (short aShort : this.getValueAsShorts()) {
                            buffer.append(aShort)
                                  .append(' ');
                        }
                        break;
                    case BYTE:
                        buffer.append(this.getValueAsByte());
                        break;
                    case STRING:
                        buffer.append('"')
                              .append(this.getValueAsString())
                              .append('"');
                        break;
                    case BYTES:
                        if (this.value != null) {
                            for (byte aValue : this.value) {
                                buffer.append(unsignedByte(aValue))
                                      .append(' ');
                            }
                        }
                        break;
        		default:
        			buffer.append("0x");
                    DHCPPacket.appendHex(buffer, this.value);
            		break;
        		}
        	} catch (IllegalArgumentException e) {
        		// fallback to bytes
                buffer.append("0x");
                DHCPPacket.appendHex(buffer, this.value);
        	}
        } else {
        	// unformatted raw output
        	buffer.append("0x");
            DHCPPacket.appendHex(buffer, this.value);
        }
    }

    /**
     * Returns a detailed string representation of the DHCP datagram.
     * 
     * <p>This multi-line string details: the static, options and padding parts
     * of the object. This is useful for debugging, but not efficient.
     * 
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();

        this.append(s);
        return s.toString();
    }

    /**
     * Convert unsigned byte to int
     */
    private static int unsignedByte(byte b) {
        return (b & 0xFF);
    }
    
    /**************************************************************************
     * 
     * Type converters.
     * 
     **************************************************************************/

    public static byte[] byte2Bytes(byte val) {
        byte[] raw = { val };
        return raw;
    }
    public static byte[] short2Bytes(short val) {
        byte[] raw = { (byte) ((val & 0xFF00) >>> 8), (byte) (val & 0XFF) };
        return raw;
    }
    public static byte[] int2Bytes(int val) {
        byte[] raw = {  (byte) ((val & 0xFF000000) >>> 24),
                		(byte) ((val & 0X00FF0000) >>> 16),
                		(byte) ((val & 0x0000FF00) >>>  8),
                		(byte) ((val & 0x000000FF)       ) };
        return raw;
    }
    public static byte[] inetAddress2Bytes(InetAddress val) {
        if (val == null){
        	return null;
        }
        if (!(val instanceof Inet4Address)) {
            throw new IllegalArgumentException("Adress must be of subclass Inet4Address");
        }
        return val.getAddress();
    }
    public static byte[] inetAddresses2Bytes(InetAddress[] val) {
        if (val == null) {
            return null;
        }
        
        byte[] buf = new byte[val.length * 4];
        for (int i=0; i<val.length; i++) {
            InetAddress addr = val[i];
            if (!(addr instanceof Inet4Address)) {
                throw new IllegalArgumentException("Adress must be of subclass Inet4Address");
            }
            System.arraycopy(addr.getAddress(), 0, buf, i*4, 4);
        }
        return buf;
    }

    /**
     * Convert DHO_USER_CLASS (77) option to a List.
     * 
     * @param buf option value of type User Class.
     * @return List of String values.
     */
    public static List<String> userClassToList(byte[] buf) {
        if (buf == null) {
            return null;
        }
        
        LinkedList<String> list = new LinkedList<String>();
        int i=0;
        while (i<buf.length) {
            int size = unsignedByte(buf[i++]);
            int instock = buf.length - i;
            if (size > instock) {
                size = instock;
            }
            list.add(DHCPPacket.bytesToString(buf, i, size));
            i += size;
        }
        return list;
    }

    /**
     * Converts DHO_USER_CLASS (77) option to a printable string
     * 
     * @param buf option value of type User Class.
     * @return printable string.
     */
    public static String userClassToString(byte[] buf) {
        if (buf == null) {
            return null;
        }
        
        List list = userClassToList(buf);
        Iterator it = list.iterator();
        StringBuffer s = new StringBuffer();
        
        while (it.hasNext()) {
            s.append('"').append((String) it.next()).append('"');
            if (it.hasNext()) {
                s.append(',');
            }
        }
        return s.toString();
    }
    /**
     * Converts this list of strings to a DHO_USER_CLASS (77) option.
     *
     * @param list the list of strings
     * @return byte[] buffer to use with <tt>setOptionRaw</tt>, <tt>null</tt> if list is null
     * @throws IllegalArgumentException if List contains anything else than String
     */
    public static byte[] stringListToUserClass(List<String> list) {
        if (list == null) { return null; }

        ByteArrayOutputStream buf = new ByteArrayOutputStream(32);
        DataOutputStream      out = new DataOutputStream(buf);

        try {
            for (String s : list) {
                byte[] bytes = DHCPPacket.stringToBytes(s);
                int    size  = bytes.length;

                if (size > 255) { size = 255; }
                out.writeByte(size);
                out.write(bytes, 0, size);
            }
            return buf.toByteArray();
        } catch (IOException e) {
            logger.log(Level.SEVERE, "Unexpected IOException", e);
            return buf.toByteArray();
        }
    }

    /**
     * Converts DHO_DHCP_AGENT_OPTIONS (82) option type to a printable string
     * 
     * @param buf option value of type Agent Option.
     * @return printable string.
     */
    public static String agentOptionsToString(byte[] buf) {
    	if (buf == null) {
    		return null;
    	}
    	
        Map<Byte, String> map = agentOptionsToMap(buf);
        StringBuffer s = new StringBuffer();
        for (Entry<Byte, String> entry : map.entrySet()) {
            s.append('{').append(unsignedByte(entry.getKey())).append("}\"");
            s.append(entry.getValue()).append('\"');
            s.append(',');
        }
        if (s.length() > 0) {
        	s.setLength(s.length() - 1);
        }

        return s.toString();
    }
    /**
     * Converts Map<Byte,String> to DHO_DHCP_AGENT_OPTIONS (82) option.
     * 
     * <p>LinkedHashMap are preferred as they preserve insertion order. Regular
     * HashMap order is randon.
     * 
     * @param map Map<Byte,String> couples
     * @return byte[] buffer to use with <tt>setOptionRaw</tt>
     * @throws IllegalArgumentException if List contains anything else than String
     */
    public static byte[] agentOptionToRaw(Map<Byte, String> map) {
    	if (map == null) {
            return null;
        }
        ByteArrayOutputStream buf = new ByteArrayOutputStream(64);
        DataOutputStream out = new DataOutputStream(buf);
        try {
        	for (Entry<Byte, String> entry : map.entrySet()) {
	            byte[] bufTemp = DHCPPacket.stringToBytes(entry.getValue());
	            int size = bufTemp.length;
	            assert (size >= 0);
	            if (size > 255) {
	            	throw new IllegalArgumentException("Value size is greater then 255 bytes");
                }
	            out.writeByte(entry.getKey());
	            out.writeByte(size);
	            out.write(bufTemp, 0, size);
        	}
	        return buf.toByteArray();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -