@Override
    public String toString() {
        StringBuilder buffer = new StringBuilder(); // output buffer

        try {
            buffer.append(this.isDhcp ? "DHCP Packet" : "BOOTP Packet")
                  .append("\ncomment=")
                  .append(this.comment)
                  .append("\naddress=")
                  .append(this.address != null ? this.address.getHostAddress() : "")
                  .append('(')
                  .append(this.port)
                  .append(')')
                  .append("\nop=");

            final Object bootName = _BOOT_NAMES.get(this.op);
            if (bootName != null) {
                buffer.append(bootName)
                      .append('(')
                      .append(this.op)
                      .append(')');
            } else {
                buffer.append(this.op);
            }

            buffer.append("\nhtype=");

            final Object htypeName = _HTYPE_NAMES.get(this.htype);
            if (htypeName != null) {
                buffer.append(htypeName)
                      .append('(')
                      .append(this.htype)
                      .append(')');
            } else {
                buffer.append(this.htype);
            }

            buffer.append("\nhlen=")
                  .append(this.hlen)
                  .append("\nhops=")
                  .append(this.hops)
                  .append("\nxid=0x");
            appendHex(buffer, this.xid);
            buffer.append("\nsecs=")
                  .append(this.secs)
                  .append("\nflags=0x")
                  .append(Integer.toHexString(this.flags))
                  .append("\nciaddr=");
            appendHostAddress(buffer, InetAddress.getByAddress(this.ciaddr));
            buffer.append("\nyiaddr=");
            appendHostAddress(buffer, InetAddress.getByAddress(this.yiaddr));
            buffer.append("\nsiaddr=");
            appendHostAddress(buffer, InetAddress.getByAddress(this.siaddr));
            buffer.append("\ngiaddr=");
            appendHostAddress(buffer, InetAddress.getByAddress(this.giaddr));
            buffer.append("\nchaddr=0x");
            this.appendChaddrAsHex(buffer);
            buffer.append("\nsname=")
                  .append(this.getSname())
                  .append("\nfile=")
                  .append(this.getFile());

            if (this.isDhcp) {
                buffer.append("\nOptions follows:");

                // parse options in creation order (LinkedHashMap)
                for (DHCPOption opt : this.getOptionsCollection()) {
                    buffer.append('\n');
                    opt.append(buffer);
                }
            }

            // padding
            buffer.append("\npadding[")
                  .append(this.padding.length)
                  .append("]=");
            appendHex(buffer, this.padding);
        } catch (Exception e) {
            // what to do ???
        }

        return buffer.toString();
    }