blob: 2658937fdb1e58910c897a5fe225e032c7859419 [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) {
44 super(0xdeadbeef, INADDR_ANY, CLIENT_ADDR, INADDR_ANY, INADDR_ANY, CLIENT_MAC, true);
45 mType = type;
46 mDomainBytes = domainBytes;
47 mVendorInfoBytes = vendorInfoBytes;
48 }
49
50 public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
51 ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
52 fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
53 DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
54 return result;
55 }
56
57 public void finishPacket(ByteBuffer buffer) {
58 addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
59 if (mDomainBytes != null) {
60 addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
61 }
62 if (mVendorInfoBytes != null) {
63 addTlv(buffer, DHCP_VENDOR_CLASS_ID, mVendorInfoBytes);
64 }
65 addTlvEnd(buffer);
66 }
67
68 // Convenience method.
69 public ByteBuffer build() {
70 // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
71 ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
72 pkt.flip();
73 return pkt;
74 }
75 }
76
77 private void assertDomainAndVendorInfoParses(
78 String expectedDomain, byte[] domainBytes,
79 String expectedVendorInfo, byte[] vendorInfoBytes) {
80 ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER,
81 domainBytes, vendorInfoBytes).build();
82 DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
83 assertEquals(expectedDomain, offerPacket.mDomainName);
84 assertEquals(expectedVendorInfo, offerPacket.mVendorId);
85 }
86
87 @SmallTest
88 public void testDomainName() throws Exception {
89 byte[] nullByte = new byte[] { 0x00 };
90 byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
91 byte[] nonNullDomain = new byte[] {
92 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
93 };
94 byte[] trailingNullDomain = new byte[] {
95 (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
96 };
97 byte[] embeddedNullsDomain = new byte[] {
98 (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
99 };
100 byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
101
102 byte[] meteredEmbeddedNull = metered.clone();
103 meteredEmbeddedNull[7] = (char) 0;
104
105 byte[] meteredTrailingNull = metered.clone();
106 meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
107
108 assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
109 assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
110 assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
111 assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
112 "ANDROID\u0000METERED", meteredEmbeddedNull);
113 assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
114 "ANDROID_METERE\u0000", meteredTrailingNull);
115 }
116}