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);
}
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;
}
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;
}
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;
}
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());
}
}
Aggregations