Search in sources :

Example 36 with Inet4Address

use of java.net.Inet4Address in project android_frameworks_base by DirtyUnicorns.

the class DhcpPacketTest method testIpAddress.

@SmallTest
public void testIpAddress() throws Exception {
    byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
    byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
    byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 };
    Inet4Address example1 = v4Address("192.0.2.1");
    Inet4Address example2 = v4Address("192.0.2.43");
    // A packet without any addresses is not valid.
    checkIpAddress(null, ANY, ANY, slash24Netmask);
    // ClientIP is used iff YourIP is not present.
    checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask);
    checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask);
    checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask);
    // Invalid netmasks are ignored.
    checkIpAddress(null, example2, ANY, invalidNetmask);
    // If there is no netmask, implicit netmasks are used.
    checkIpAddress("192.0.2.43/24", ANY, example2, null);
}
Also used : Inet4Address(java.net.Inet4Address) SmallTest(android.test.suitebuilder.annotation.SmallTest)

Example 37 with Inet4Address

use of java.net.Inet4Address in project android_frameworks_base by DirtyUnicorns.

the class DhcpAckPacket method buildPacket.

/**
     * Fills in a packet with the requested ACK parameters.
     */
public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
    ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
    Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
    Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
    fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
    result.flip();
    return result;
}
Also used : Inet4Address(java.net.Inet4Address) ByteBuffer(java.nio.ByteBuffer)

Example 38 with Inet4Address

use of java.net.Inet4Address in project android_frameworks_base by DirtyUnicorns.

the class DhcpNakPacket method buildPacket.

/**
     * Fills in a packet with the requested NAK attributes.
     */
public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
    ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
    Inet4Address destIp = mClientIp;
    Inet4Address srcIp = mYourIp;
    fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
    result.flip();
    return result;
}
Also used : Inet4Address(java.net.Inet4Address) ByteBuffer(java.nio.ByteBuffer)

Example 39 with Inet4Address

use of java.net.Inet4Address in project android_frameworks_base by DirtyUnicorns.

the class DhcpPacket method decodeFullPacket.

/**
     * Creates a concrete DhcpPacket from the supplied ByteBuffer.  The
     * buffer may have an L2 encapsulation (which is the full EthernetII
     * format starting with the source-address MAC) or an L3 encapsulation
     * (which starts with the IP header).
     * <br>
     * A subset of the optional parameters are parsed and are stored
     * in object fields.
     */
@VisibleForTesting
static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException {
    // bootp parameters
    int transactionId;
    short secs;
    Inet4Address clientIp;
    Inet4Address yourIp;
    Inet4Address nextIp;
    Inet4Address relayIp;
    byte[] clientMac;
    List<Inet4Address> dnsServers = new ArrayList<>();
    // aka router
    List<Inet4Address> gateways = new ArrayList<>();
    Inet4Address serverIdentifier = null;
    Inet4Address netMask = null;
    String message = null;
    String vendorId = null;
    String vendorInfo = null;
    byte[] expectedParams = null;
    String hostName = null;
    String domainName = null;
    Inet4Address ipSrc = null;
    Inet4Address ipDst = null;
    Inet4Address bcAddr = null;
    Inet4Address requestedIp = null;
    // The following are all unsigned integers. Internally we store them as signed integers of
    // the same length because that way we're guaranteed that they can't be out of the range of
    // the unsigned field in the packet. Callers wanting to pass in an unsigned value will need
    // to cast it.
    Short mtu = null;
    Short maxMessageSize = null;
    Integer leaseTime = null;
    Integer T1 = null;
    Integer T2 = null;
    // dhcp options
    byte dhcpType = (byte) 0xFF;
    packet.order(ByteOrder.BIG_ENDIAN);
    // check to see if we need to parse L2, IP, and UDP encaps
    if (pktType == ENCAP_L2) {
        if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
            throw new ParseException(DhcpErrorEvent.L2_TOO_SHORT, "L2 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L2);
        }
        byte[] l2dst = new byte[6];
        byte[] l2src = new byte[6];
        packet.get(l2dst);
        packet.get(l2src);
        short l2type = packet.getShort();
        if (l2type != OsConstants.ETH_P_IP) {
            throw new ParseException(DhcpErrorEvent.L2_WRONG_ETH_TYPE, "Unexpected L2 type 0x%04x, expected 0x%04x", l2type, OsConstants.ETH_P_IP);
        }
    }
    if (pktType <= ENCAP_L3) {
        if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
            throw new ParseException(DhcpErrorEvent.L3_TOO_SHORT, "L3 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L3);
        }
        byte ipTypeAndLength = packet.get();
        int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
        if (ipVersion != 4) {
            throw new ParseException(DhcpErrorEvent.L3_NOT_IPV4, "Invalid IP version %d", ipVersion);
        }
        // System.out.println("ipType is " + ipType);
        byte ipDiffServicesField = packet.get();
        short ipTotalLength = packet.getShort();
        short ipIdentification = packet.getShort();
        byte ipFlags = packet.get();
        byte ipFragOffset = packet.get();
        byte ipTTL = packet.get();
        byte ipProto = packet.get();
        short ipChksm = packet.getShort();
        ipSrc = readIpAddress(packet);
        ipDst = readIpAddress(packet);
        if (ipProto != IP_TYPE_UDP) {
            throw new ParseException(DhcpErrorEvent.L4_NOT_UDP, "Protocol not UDP: %d", ipProto);
        }
        // Skip options. This cannot cause us to read beyond the end of the buffer because the
        // IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
        // MIN_PACKET_LENGTH_L3.
        int optionWords = ((ipTypeAndLength & 0x0f) - 5);
        for (int i = 0; i < optionWords; i++) {
            packet.getInt();
        }
        // assume UDP
        short udpSrcPort = packet.getShort();
        short udpDstPort = packet.getShort();
        short udpLen = packet.getShort();
        short udpChkSum = packet.getShort();
        // server-to-server packets, e.g. for relays.
        if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) && !isPacketServerToServer(udpSrcPort, udpDstPort)) {
            // filter is set. http://b/26696823 .
            throw new ParseException(DhcpErrorEvent.L4_WRONG_PORT, "Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
        }
    }
    // We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
    if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
        throw new ParseException(DhcpErrorEvent.BOOTP_TOO_SHORT, "Invalid type or BOOTP packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
    }
    byte type = packet.get();
    byte hwType = packet.get();
    int addrLen = packet.get() & 0xff;
    byte hops = packet.get();
    transactionId = packet.getInt();
    secs = packet.getShort();
    short bootpFlags = packet.getShort();
    boolean broadcast = (bootpFlags & 0x8000) != 0;
    byte[] ipv4addr = new byte[4];
    try {
        packet.get(ipv4addr);
        clientIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
        packet.get(ipv4addr);
        yourIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
        packet.get(ipv4addr);
        nextIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
        packet.get(ipv4addr);
        relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
    } catch (UnknownHostException ex) {
        throw new ParseException(DhcpErrorEvent.L3_INVALID_IP, "Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
    }
    // TODO: evaluate whether to make this test more liberal.
    if (addrLen > HWADDR_LEN) {
        addrLen = ETHER_BROADCAST.length;
    }
    clientMac = new byte[addrLen];
    packet.get(clientMac);
    // skip over address padding (16 octets allocated)
    packet.position(packet.position() + (16 - addrLen) + // skip server host name (64 chars)
    64 + // skip boot file name (128 chars)
    128);
    // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
    if (packet.remaining() < 4) {
        throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
    }
    int dhcpMagicCookie = packet.getInt();
    if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
        throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE, "Bad magic cookie 0x%08x, should be 0x%08x", dhcpMagicCookie, DHCP_MAGIC_COOKIE);
    }
    // parse options
    boolean notFinishedOptions = true;
    while ((packet.position() < packet.limit()) && notFinishedOptions) {
        // cannot underflow because position < limit
        final byte optionType = packet.get();
        try {
            if (optionType == DHCP_OPTION_END) {
                notFinishedOptions = false;
            } else if (optionType == DHCP_OPTION_PAD) {
            // The pad option doesn't have a length field. Nothing to do.
            } else {
                int optionLen = packet.get() & 0xFF;
                int expectedLen = 0;
                switch(optionType) {
                    case DHCP_SUBNET_MASK:
                        netMask = readIpAddress(packet);
                        expectedLen = 4;
                        break;
                    case DHCP_ROUTER:
                        for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
                            gateways.add(readIpAddress(packet));
                        }
                        break;
                    case DHCP_DNS_SERVER:
                        for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
                            dnsServers.add(readIpAddress(packet));
                        }
                        break;
                    case DHCP_HOST_NAME:
                        expectedLen = optionLen;
                        hostName = readAsciiString(packet, optionLen, false);
                        break;
                    case DHCP_MTU:
                        expectedLen = 2;
                        mtu = packet.getShort();
                        break;
                    case DHCP_DOMAIN_NAME:
                        expectedLen = optionLen;
                        domainName = readAsciiString(packet, optionLen, false);
                        break;
                    case DHCP_BROADCAST_ADDRESS:
                        bcAddr = readIpAddress(packet);
                        expectedLen = 4;
                        break;
                    case DHCP_REQUESTED_IP:
                        requestedIp = readIpAddress(packet);
                        expectedLen = 4;
                        break;
                    case DHCP_LEASE_TIME:
                        leaseTime = Integer.valueOf(packet.getInt());
                        expectedLen = 4;
                        break;
                    case DHCP_MESSAGE_TYPE:
                        dhcpType = packet.get();
                        expectedLen = 1;
                        break;
                    case DHCP_SERVER_IDENTIFIER:
                        serverIdentifier = readIpAddress(packet);
                        expectedLen = 4;
                        break;
                    case DHCP_PARAMETER_LIST:
                        expectedParams = new byte[optionLen];
                        packet.get(expectedParams);
                        expectedLen = optionLen;
                        break;
                    case DHCP_MESSAGE:
                        expectedLen = optionLen;
                        message = readAsciiString(packet, optionLen, false);
                        break;
                    case DHCP_MAX_MESSAGE_SIZE:
                        expectedLen = 2;
                        maxMessageSize = Short.valueOf(packet.getShort());
                        break;
                    case DHCP_RENEWAL_TIME:
                        expectedLen = 4;
                        T1 = Integer.valueOf(packet.getInt());
                        break;
                    case DHCP_REBINDING_TIME:
                        expectedLen = 4;
                        T2 = Integer.valueOf(packet.getInt());
                        break;
                    case DHCP_VENDOR_CLASS_ID:
                        expectedLen = optionLen;
                        // Embedded nulls are safe as this does not get passed to netd.
                        vendorId = readAsciiString(packet, optionLen, true);
                        break;
                    case DHCP_CLIENT_IDENTIFIER:
                        {
                            // Client identifier
                            byte[] id = new byte[optionLen];
                            packet.get(id);
                            expectedLen = optionLen;
                        }
                        break;
                    case DHCP_VENDOR_INFO:
                        expectedLen = optionLen;
                        // Embedded nulls are safe as this does not get passed to netd.
                        vendorInfo = readAsciiString(packet, optionLen, true);
                        break;
                    default:
                        // ignore any other parameters
                        for (int i = 0; i < optionLen; i++) {
                            expectedLen++;
                            byte throwaway = packet.get();
                        }
                }
                if (expectedLen != optionLen) {
                    final int errorCode = DhcpErrorEvent.errorCodeWithOption(DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH, optionType);
                    throw new ParseException(errorCode, "Invalid length %d for option %d, expected %d", optionLen, optionType, expectedLen);
                }
            }
        } catch (BufferUnderflowException e) {
            final int errorCode = DhcpErrorEvent.errorCodeWithOption(DhcpErrorEvent.BUFFER_UNDERFLOW, optionType);
            throw new ParseException(errorCode, "BufferUnderflowException");
        }
    }
    DhcpPacket newPacket;
    switch(dhcpType) {
        case (byte) 0xFF:
            throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE, "No DHCP message type option");
        case DHCP_MESSAGE_TYPE_DISCOVER:
            newPacket = new DhcpDiscoverPacket(transactionId, secs, clientMac, broadcast);
            break;
        case DHCP_MESSAGE_TYPE_OFFER:
            newPacket = new DhcpOfferPacket(transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac);
            break;
        case DHCP_MESSAGE_TYPE_REQUEST:
            newPacket = new DhcpRequestPacket(transactionId, secs, clientIp, clientMac, broadcast);
            break;
        case DHCP_MESSAGE_TYPE_DECLINE:
            newPacket = new DhcpDeclinePacket(transactionId, secs, clientIp, yourIp, nextIp, relayIp, clientMac);
            break;
        case DHCP_MESSAGE_TYPE_ACK:
            newPacket = new DhcpAckPacket(transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac);
            break;
        case DHCP_MESSAGE_TYPE_NAK:
            newPacket = new DhcpNakPacket(transactionId, secs, clientIp, yourIp, nextIp, relayIp, clientMac);
            break;
        case DHCP_MESSAGE_TYPE_INFORM:
            newPacket = new DhcpInformPacket(transactionId, secs, clientIp, yourIp, nextIp, relayIp, clientMac);
            break;
        default:
            throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE, "Unimplemented DHCP type %d", dhcpType);
    }
    newPacket.mBroadcastAddress = bcAddr;
    newPacket.mDnsServers = dnsServers;
    newPacket.mDomainName = domainName;
    newPacket.mGateways = gateways;
    newPacket.mHostName = hostName;
    newPacket.mLeaseTime = leaseTime;
    newPacket.mMessage = message;
    newPacket.mMtu = mtu;
    newPacket.mRequestedIp = requestedIp;
    newPacket.mRequestedParams = expectedParams;
    newPacket.mServerIdentifier = serverIdentifier;
    newPacket.mSubnetMask = netMask;
    newPacket.mMaxMessageSize = maxMessageSize;
    newPacket.mT1 = T1;
    newPacket.mT2 = T2;
    newPacket.mVendorId = vendorId;
    newPacket.mVendorInfo = vendorInfo;
    return newPacket;
}
Also used : Inet4Address(java.net.Inet4Address) UnknownHostException(java.net.UnknownHostException) ArrayList(java.util.ArrayList) BufferUnderflowException(java.nio.BufferUnderflowException) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 40 with Inet4Address

use of java.net.Inet4Address in project android_frameworks_base by DirtyUnicorns.

the class DhcpPacket method addTlv.

/**
     * Adds an optional parameter containing a list of IP addresses.
     */
protected static void addTlv(ByteBuffer buf, byte type, List<Inet4Address> addrs) {
    if (addrs == null || addrs.size() == 0)
        return;
    int optionLen = 4 * addrs.size();
    if (optionLen > MAX_OPTION_LEN) {
        throw new IllegalArgumentException("DHCP option too long: " + optionLen + " vs. " + MAX_OPTION_LEN);
    }
    buf.put(type);
    buf.put((byte) (optionLen));
    for (Inet4Address addr : addrs) {
        buf.put(addr.getAddress());
    }
}
Also used : Inet4Address(java.net.Inet4Address)

Aggregations

Inet4Address (java.net.Inet4Address)184 InetAddress (java.net.InetAddress)85 Inet6Address (java.net.Inet6Address)45 NetworkInterface (java.net.NetworkInterface)39 UnknownHostException (java.net.UnknownHostException)28 LinkAddress (android.net.LinkAddress)24 SocketException (java.net.SocketException)23 IOException (java.io.IOException)22 ArrayList (java.util.ArrayList)19 InterfaceAddress (java.net.InterfaceAddress)17 ByteBuffer (java.nio.ByteBuffer)17 RouteInfo (android.net.RouteInfo)12 LinkProperties (android.net.LinkProperties)7 InetSocketAddress (java.net.InetSocketAddress)6 Test (org.junit.Test)6 WifiDisplay (android.hardware.display.WifiDisplay)5 WifiDisplaySessionInfo (android.hardware.display.WifiDisplaySessionInfo)5 DhcpResults (android.net.DhcpResults)5 IpConfiguration (android.net.IpConfiguration)5 IpAssignment (android.net.IpConfiguration.IpAssignment)5