blob: f11604226a067a793555ef9f00344ee17b9a5f60 [file] [log] [blame]
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +09001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net.dhcp;
18
19import android.net.NetworkUtils;
Lorenzo Colittid9735372015-06-02 13:15:50 +090020import android.net.DhcpResults;
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090021import android.system.OsConstants;
22import android.test.suitebuilder.annotation.SmallTest;
23import junit.framework.TestCase;
24
25import java.net.Inet4Address;
26import java.nio.ByteBuffer;
27
28import static android.net.dhcp.DhcpPacket.*;
29
30
31public class DhcpPacketTest extends TestCase {
32
33 private static Inet4Address SERVER_ADDR =
34 (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.1");
35 private static Inet4Address CLIENT_ADDR =
36 (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.234");
37 private static byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
38
39 class TestDhcpPacket extends DhcpPacket {
40 private byte mType;
41 // TODO: Make this a map of option numbers to bytes instead.
Lorenzo Colittid9735372015-06-02 13:15:50 +090042 private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes;
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090043
Lorenzo Colittid9735372015-06-02 13:15:50 +090044 public TestDhcpPacket(byte type) {
Lorenzo Colitti3e979322015-04-21 15:22:17 +090045 super(0xdeadbeef, (short) 0, INADDR_ANY, CLIENT_ADDR, INADDR_ANY, INADDR_ANY,
46 CLIENT_MAC, true);
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090047 mType = type;
Lorenzo Colittid9735372015-06-02 13:15:50 +090048 }
49
50 public TestDhcpPacket setDomainBytes(byte[] domainBytes) {
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090051 mDomainBytes = domainBytes;
Lorenzo Colittid9735372015-06-02 13:15:50 +090052 return this;
53 }
54
55 public TestDhcpPacket setVendorInfoBytes(byte[] vendorInfoBytes) {
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090056 mVendorInfoBytes = vendorInfoBytes;
Lorenzo Colittid9735372015-06-02 13:15:50 +090057 return this;
58 }
59
60 public TestDhcpPacket setLeaseTimeBytes(byte[] leaseTimeBytes) {
61 mLeaseTimeBytes = leaseTimeBytes;
62 return this;
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090063 }
64
65 public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
66 ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
67 fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
68 DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
69 return result;
70 }
71
72 public void finishPacket(ByteBuffer buffer) {
73 addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
74 if (mDomainBytes != null) {
75 addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
76 }
77 if (mVendorInfoBytes != null) {
78 addTlv(buffer, DHCP_VENDOR_CLASS_ID, mVendorInfoBytes);
79 }
Lorenzo Colittid9735372015-06-02 13:15:50 +090080 if (mLeaseTimeBytes != null) {
81 addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes);
82 }
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090083 addTlvEnd(buffer);
84 }
85
86 // Convenience method.
87 public ByteBuffer build() {
88 // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
89 ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
90 pkt.flip();
91 return pkt;
92 }
93 }
94
95 private void assertDomainAndVendorInfoParses(
96 String expectedDomain, byte[] domainBytes,
97 String expectedVendorInfo, byte[] vendorInfoBytes) {
Lorenzo Colittid9735372015-06-02 13:15:50 +090098 ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
99 .setDomainBytes(domainBytes)
100 .setVendorInfoBytes(vendorInfoBytes)
101 .build();
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +0900102 DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
103 assertEquals(expectedDomain, offerPacket.mDomainName);
104 assertEquals(expectedVendorInfo, offerPacket.mVendorId);
105 }
106
107 @SmallTest
108 public void testDomainName() throws Exception {
109 byte[] nullByte = new byte[] { 0x00 };
110 byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
111 byte[] nonNullDomain = new byte[] {
112 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
113 };
114 byte[] trailingNullDomain = new byte[] {
115 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
116 };
117 byte[] embeddedNullsDomain = new byte[] {
118 (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
119 };
120 byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
121
122 byte[] meteredEmbeddedNull = metered.clone();
123 meteredEmbeddedNull[7] = (char) 0;
124
125 byte[] meteredTrailingNull = metered.clone();
126 meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
127
128 assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
129 assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
130 assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
131 assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
132 "ANDROID\u0000METERED", meteredEmbeddedNull);
133 assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
134 "ANDROID_METERE\u0000", meteredTrailingNull);
135 }
Lorenzo Colittid9735372015-06-02 13:15:50 +0900136
137 private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
138 long leaseTimeMillis, byte[] leaseTimeBytes) {
139 TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
140 if (leaseTimeBytes != null) {
141 testPacket.setLeaseTimeBytes(leaseTimeBytes);
142 }
143 ByteBuffer packet = testPacket.build();
144 DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
145 if (!expectValid) {
146 assertNull(offerPacket);
147 return;
148 }
149 assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
150 DhcpResults dhcpResults = offerPacket.toDhcpResults(); // Just check this doesn't crash.
151 assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
152 }
153
154 @SmallTest
155 public void testLeaseTime() throws Exception {
156 byte[] noLease = null;
157 byte[] tooShortLease = new byte[] { 0x00, 0x00 };
158 byte[] tooLongLease = new byte[] { 0x00, 0x00, 0x00, 60, 0x01 };
159 byte[] zeroLease = new byte[] { 0x00, 0x00, 0x00, 0x00 };
160 byte[] tenSecondLease = new byte[] { 0x00, 0x00, 0x00, 10 };
161 byte[] oneMinuteLease = new byte[] { 0x00, 0x00, 0x00, 60 };
162 byte[] fiveMinuteLease = new byte[] { 0x00, 0x00, 0x01, 0x2c };
163 byte[] oneDayLease = new byte[] { 0x00, 0x01, 0x51, (byte) 0x80 };
164 byte[] maxIntPlusOneLease = new byte[] { (byte) 0x80, 0x00, 0x00, 0x01 };
165 byte[] infiniteLease = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
166
167 assertLeaseTimeParses(true, null, 0, noLease);
168 assertLeaseTimeParses(false, null, 0, tooShortLease);
169 assertLeaseTimeParses(false, null, 0, tooLongLease);
170 assertLeaseTimeParses(true, 0, 60 * 1000, zeroLease);
171 assertLeaseTimeParses(true, 10, 60 * 1000, tenSecondLease);
172 assertLeaseTimeParses(true, 60, 60 * 1000, oneMinuteLease);
173 assertLeaseTimeParses(true, 300, 300 * 1000, fiveMinuteLease);
174 assertLeaseTimeParses(true, 86400, 86400 * 1000, oneDayLease);
175 assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease);
176 assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease);
177 }
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +0900178}