blob: 4f7c7ec8f57480cca10acad01baced0459c398bb [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;
20import android.system.OsConstants;
21import android.test.suitebuilder.annotation.SmallTest;
22import junit.framework.TestCase;
23
24import java.net.Inet4Address;
25import java.nio.ByteBuffer;
26
27import static android.net.dhcp.DhcpPacket.*;
28
29
30public class DhcpPacketTest extends TestCase {
31
32 private static Inet4Address SERVER_ADDR =
33 (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.1");
34 private static Inet4Address CLIENT_ADDR =
35 (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.234");
36 private static byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
37
38 class TestDhcpPacket extends DhcpPacket {
39 private byte mType;
40 // TODO: Make this a map of option numbers to bytes instead.
41 private byte[] mDomainBytes, mVendorInfoBytes;
42
43 public TestDhcpPacket(byte type, byte[] domainBytes, byte[] vendorInfoBytes) {
Lorenzo Colitti3e979322015-04-21 15:22:17 +090044 super(0xdeadbeef, (short) 0, INADDR_ANY, CLIENT_ADDR, INADDR_ANY, INADDR_ANY,
45 CLIENT_MAC, true);
Lorenzo Colittic2abb2b2015-03-31 16:26:57 +090046 mType = type;
47 mDomainBytes = domainBytes;
48 mVendorInfoBytes = vendorInfoBytes;
49 }
50
51 public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
52 ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
53 fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
54 DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
55 return result;
56 }
57
58 public void finishPacket(ByteBuffer buffer) {
59 addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
60 if (mDomainBytes != null) {
61 addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
62 }
63 if (mVendorInfoBytes != null) {
64 addTlv(buffer, DHCP_VENDOR_CLASS_ID, mVendorInfoBytes);
65 }
66 addTlvEnd(buffer);
67 }
68
69 // Convenience method.
70 public ByteBuffer build() {
71 // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
72 ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
73 pkt.flip();
74 return pkt;
75 }
76 }
77
78 private void assertDomainAndVendorInfoParses(
79 String expectedDomain, byte[] domainBytes,
80 String expectedVendorInfo, byte[] vendorInfoBytes) {
81 ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER,
82 domainBytes, vendorInfoBytes).build();
83 DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
84 assertEquals(expectedDomain, offerPacket.mDomainName);
85 assertEquals(expectedVendorInfo, offerPacket.mVendorId);
86 }
87
88 @SmallTest
89 public void testDomainName() throws Exception {
90 byte[] nullByte = new byte[] { 0x00 };
91 byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
92 byte[] nonNullDomain = new byte[] {
93 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
94 };
95 byte[] trailingNullDomain = new byte[] {
96 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
97 };
98 byte[] embeddedNullsDomain = new byte[] {
99 (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
100 };
101 byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
102
103 byte[] meteredEmbeddedNull = metered.clone();
104 meteredEmbeddedNull[7] = (char) 0;
105
106 byte[] meteredTrailingNull = metered.clone();
107 meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
108
109 assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
110 assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
111 assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
112 assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
113 "ANDROID\u0000METERED", meteredEmbeddedNull);
114 assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
115 "ANDROID_METERE\u0000", meteredTrailingNull);
116 }
117}