Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2014 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 
     17 package android.net;
     18 
     19 import android.net.IpPrefix;
     20 import android.os.Parcel;
     21 import static android.test.MoreAsserts.assertNotEqual;
     22 import android.test.suitebuilder.annotation.SmallTest;
     23 
     24 import static org.junit.Assert.assertArrayEquals;
     25 import java.net.InetAddress;
     26 import java.util.Random;
     27 import junit.framework.TestCase;
     28 
     29 
     30 public class IpPrefixTest extends TestCase {
     31 
     32     // Explicitly cast everything to byte because "error: possible loss of precision".
     33     private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4};
     34     private static final byte[] IPV6_BYTES = {
     35         (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
     36         (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
     37         (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00,
     38         (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xa0
     39     };
     40 
     41     @SmallTest
     42     public void testConstructor() {
     43         IpPrefix p;
     44         try {
     45             p = new IpPrefix((byte[]) null, 9);
     46             fail("Expected NullPointerException: null byte array");
     47         } catch(RuntimeException expected) {}
     48 
     49         try {
     50             p = new IpPrefix((InetAddress) null, 10);
     51             fail("Expected NullPointerException: null InetAddress");
     52         } catch(RuntimeException expected) {}
     53 
     54         try {
     55             p = new IpPrefix((String) null);
     56             fail("Expected NullPointerException: null String");
     57         } catch(RuntimeException expected) {}
     58 
     59 
     60         try {
     61             byte[] b2 = {1, 2, 3, 4, 5};
     62             p = new IpPrefix(b2, 29);
     63             fail("Expected IllegalArgumentException: invalid array length");
     64         } catch(IllegalArgumentException expected) {}
     65 
     66         try {
     67             p = new IpPrefix("1.2.3.4");
     68             fail("Expected IllegalArgumentException: no prefix length");
     69         } catch(IllegalArgumentException expected) {}
     70 
     71         try {
     72             p = new IpPrefix("1.2.3.4/");
     73             fail("Expected IllegalArgumentException: empty prefix length");
     74         } catch(IllegalArgumentException expected) {}
     75 
     76         try {
     77             p = new IpPrefix("foo/32");
     78             fail("Expected IllegalArgumentException: invalid address");
     79         } catch(IllegalArgumentException expected) {}
     80 
     81         try {
     82             p = new IpPrefix("1/32");
     83             fail("Expected IllegalArgumentException: deprecated IPv4 format");
     84         } catch(IllegalArgumentException expected) {}
     85 
     86         try {
     87             p = new IpPrefix("1.2.3.256/32");
     88             fail("Expected IllegalArgumentException: invalid IPv4 address");
     89         } catch(IllegalArgumentException expected) {}
     90 
     91         try {
     92             p = new IpPrefix("foo/32");
     93             fail("Expected IllegalArgumentException: non-address");
     94         } catch(IllegalArgumentException expected) {}
     95 
     96         try {
     97             p = new IpPrefix("f00:::/32");
     98             fail("Expected IllegalArgumentException: invalid IPv6 address");
     99         } catch(IllegalArgumentException expected) {}
    100     }
    101 
    102     public void testTruncation() {
    103         IpPrefix p;
    104 
    105         p = new IpPrefix(IPV4_BYTES, 32);
    106         assertEquals("192.0.2.4/32", p.toString());
    107 
    108         p = new IpPrefix(IPV4_BYTES, 29);
    109         assertEquals("192.0.2.0/29", p.toString());
    110 
    111         p = new IpPrefix(IPV4_BYTES, 8);
    112         assertEquals("192.0.0.0/8", p.toString());
    113 
    114         p = new IpPrefix(IPV4_BYTES, 0);
    115         assertEquals("0.0.0.0/0", p.toString());
    116 
    117         try {
    118             p = new IpPrefix(IPV4_BYTES, 33);
    119             fail("Expected IllegalArgumentException: invalid prefix length");
    120         } catch(RuntimeException expected) {}
    121 
    122         try {
    123             p = new IpPrefix(IPV4_BYTES, 128);
    124             fail("Expected IllegalArgumentException: invalid prefix length");
    125         } catch(RuntimeException expected) {}
    126 
    127         try {
    128             p = new IpPrefix(IPV4_BYTES, -1);
    129             fail("Expected IllegalArgumentException: negative prefix length");
    130         } catch(RuntimeException expected) {}
    131 
    132         p = new IpPrefix(IPV6_BYTES, 128);
    133         assertEquals("2001:db8:dead:beef:f00::a0/128", p.toString());
    134 
    135         p = new IpPrefix(IPV6_BYTES, 122);
    136         assertEquals("2001:db8:dead:beef:f00::80/122", p.toString());
    137 
    138         p = new IpPrefix(IPV6_BYTES, 64);
    139         assertEquals("2001:db8:dead:beef::/64", p.toString());
    140 
    141         p = new IpPrefix(IPV6_BYTES, 3);
    142         assertEquals("2000::/3", p.toString());
    143 
    144         p = new IpPrefix(IPV6_BYTES, 0);
    145         assertEquals("::/0", p.toString());
    146 
    147         try {
    148             p = new IpPrefix(IPV6_BYTES, -1);
    149             fail("Expected IllegalArgumentException: negative prefix length");
    150         } catch(RuntimeException expected) {}
    151 
    152         try {
    153             p = new IpPrefix(IPV6_BYTES, 129);
    154             fail("Expected IllegalArgumentException: negative prefix length");
    155         } catch(RuntimeException expected) {}
    156 
    157     }
    158 
    159     private void assertAreEqual(Object o1, Object o2) {
    160         assertTrue(o1.equals(o2));
    161         assertTrue(o2.equals(o1));
    162     }
    163 
    164     private void assertAreNotEqual(Object o1, Object o2) {
    165         assertFalse(o1.equals(o2));
    166         assertFalse(o2.equals(o1));
    167     }
    168 
    169     @SmallTest
    170     public void testEquals() {
    171         IpPrefix p1, p2;
    172 
    173         p1 = new IpPrefix("192.0.2.251/23");
    174         p2 = new IpPrefix(new byte[]{(byte) 192, (byte) 0, (byte) 2, (byte) 251}, 23);
    175         assertAreEqual(p1, p2);
    176 
    177         p1 = new IpPrefix("192.0.2.5/23");
    178         assertAreEqual(p1, p2);
    179 
    180         p1 = new IpPrefix("192.0.2.5/24");
    181         assertAreNotEqual(p1, p2);
    182 
    183         p1 = new IpPrefix("192.0.4.5/23");
    184         assertAreNotEqual(p1, p2);
    185 
    186 
    187         p1 = new IpPrefix("2001:db8:dead:beef:f00::80/122");
    188         p2 = new IpPrefix(IPV6_BYTES, 122);
    189         assertEquals("2001:db8:dead:beef:f00::80/122", p2.toString());
    190         assertAreEqual(p1, p2);
    191 
    192         p1 = new IpPrefix("2001:db8:dead:beef:f00::bf/122");
    193         assertAreEqual(p1, p2);
    194 
    195         p1 = new IpPrefix("2001:db8:dead:beef:f00::8:0/123");
    196         assertAreNotEqual(p1, p2);
    197 
    198         p1 = new IpPrefix("2001:db8:dead:beef::/122");
    199         assertAreNotEqual(p1, p2);
    200 
    201         // 192.0.2.4/32 != c000:0204::/32.
    202         byte[] ipv6bytes = new byte[16];
    203         System.arraycopy(IPV4_BYTES, 0, ipv6bytes, 0, IPV4_BYTES.length);
    204         p1 = new IpPrefix(ipv6bytes, 32);
    205         assertAreEqual(p1, new IpPrefix("c000:0204::/32"));
    206 
    207         p2 = new IpPrefix(IPV4_BYTES, 32);
    208         assertAreNotEqual(p1, p2);
    209     }
    210 
    211     @SmallTest
    212     public void testHashCode() {
    213         IpPrefix p;
    214         int oldCode = -1;
    215         Random random = new Random();
    216         for (int i = 0; i < 100; i++) {
    217             if (random.nextBoolean()) {
    218                 // IPv4.
    219                 byte[] b = new byte[4];
    220                 random.nextBytes(b);
    221                 p = new IpPrefix(b, random.nextInt(33));
    222                 assertNotEqual(oldCode, p.hashCode());
    223                 oldCode = p.hashCode();
    224             } else {
    225                 // IPv6.
    226                 byte[] b = new byte[16];
    227                 random.nextBytes(b);
    228                 p = new IpPrefix(b, random.nextInt(129));
    229                 assertNotEqual(oldCode, p.hashCode());
    230                 oldCode = p.hashCode();
    231             }
    232         }
    233     }
    234 
    235     @SmallTest
    236     public void testMappedAddressesAreBroken() {
    237         // 192.0.2.0/24 != ::ffff:c000:0204/120, but because we use InetAddress,
    238         // we are unable to comprehend that.
    239         byte[] ipv6bytes = {
    240             (byte) 0, (byte) 0, (byte) 0, (byte) 0,
    241             (byte) 0, (byte) 0, (byte) 0, (byte) 0,
    242             (byte) 0, (byte) 0, (byte) 0xff, (byte) 0xff,
    243             (byte) 192, (byte) 0, (byte) 2, (byte) 0};
    244         IpPrefix p = new IpPrefix(ipv6bytes, 120);
    245         assertEquals(16, p.getRawAddress().length);       // Fine.
    246         assertArrayEquals(ipv6bytes, p.getRawAddress());  // Fine.
    247 
    248         // Broken.
    249         assertEquals("192.0.2.0/120", p.toString());
    250         assertEquals(InetAddress.parseNumericAddress("192.0.2.0"), p.getAddress());
    251     }
    252 
    253     public IpPrefix passThroughParcel(IpPrefix p) {
    254         Parcel parcel = Parcel.obtain();
    255         IpPrefix p2 = null;
    256         try {
    257             p.writeToParcel(parcel, 0);
    258             parcel.setDataPosition(0);
    259             p2 = IpPrefix.CREATOR.createFromParcel(parcel);
    260         } finally {
    261             parcel.recycle();
    262         }
    263         assertNotNull(p2);
    264         return p2;
    265     }
    266 
    267     public void assertParcelingIsLossless(IpPrefix p) {
    268       IpPrefix p2 = passThroughParcel(p);
    269       assertEquals(p, p2);
    270     }
    271 
    272     public void testParceling() {
    273         IpPrefix p;
    274 
    275         p = new IpPrefix("2001:4860:db8::/64");
    276         assertParcelingIsLossless(p);
    277 
    278         p = new IpPrefix("192.0.2.0/25");
    279         assertParcelingIsLossless(p);
    280     }
    281 }
    282