blob: c664a3af207322b888b73a272b6fd62d70baae4d [file] [log] [blame]
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -07001package org.onlab.packet;
2
3import java.util.Arrays;
4
5/**
6 * A class representing an IPv4 address.
7 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -07008public class IpAddress {
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -07009
10 //IP Versions
11 public enum Version { INET, INET6 };
12
Ayaka Koshibe04a1a4e2014-09-11 14:31:29 -070013 //lengths of address, in bytes
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070014 public static final int INET_LEN = 4;
Ayaka Koshibe3a25aec2014-09-12 11:52:53 -070015 public static final int INET6_LEN = 16;
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070016
17 protected Version version;
18 //does it make more sense to have a integral address?
19 protected byte[] octets;
20
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070021 protected IpAddress(Version ver, byte[] octets) {
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070022 this.version = ver;
23 this.octets = Arrays.copyOf(octets, INET_LEN);
24 }
25
26 /**
27 * Converts a byte array into an IP address.
28 *
29 * @param address a byte array
30 * @return an IP address
31 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070032 public static IpAddress valueOf(byte [] address) {
33 return new IpAddress(Version.INET, address);
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070034 }
35
36 /**
37 * Converts an integer into an IPv4 address.
38 *
39 * @param address an integer representing an IP value
40 * @return an IP address
41 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070042 public static IpAddress valueOf(int address) {
Ayaka Koshibe16698a32014-09-13 22:19:02 -070043 byte [] bytes = new byte [INET_LEN];
44 for (int i = 0; i < INET_LEN; i++) {
45 bytes[i] = (byte) ((address >> (INET_LEN - (i + 1)) * 8) & 0xff);
46 }
47
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070048 return new IpAddress(Version.INET, bytes);
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070049 }
50
51 /**
52 * Converts a string in dotted-decimal notation (x.x.x.x) into
53 * an IPv4 address.
54 *
55 * @param address a string representing an IP address, e.g. "10.0.0.1"
56 * @return an IP address
57 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070058 public static IpAddress valueOf(String address) {
Ayaka Koshibe50ee9242014-09-12 16:37:46 -070059 final String [] parts = address.split("\\.");
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070060 if (parts.length != INET_LEN) {
61 throw new IllegalArgumentException("Malformed IP address string; "
62 + "Addres must have four decimal values separated by dots (.)");
63 }
64 final byte [] bytes = new byte[INET_LEN];
65 for (int i = 0; i < INET_LEN; i++) {
66 bytes[i] = Byte.parseByte(parts[i], 10);
67 }
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070068 return new IpAddress(Version.INET, bytes);
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070069 }
70
71 /**
72 * Returns the IP version of this address.
73 *
74 * @return the version
75 */
76 public Version version() {
77 return this.version;
78 }
79
80 /**
81 * Returns the IP address as a byte array.
82 *
83 * @return a byte array
84 */
85 public byte [] toOctets() {
86 return Arrays.copyOf(this.octets, INET_LEN);
87 }
88
Ayaka Koshibe16698a32014-09-13 22:19:02 -070089 /**
90 * Returns the integral value of this IP address.
91 *
92 * @return the IP address's value as an integer
93 */
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070094 public int toInt() {
Ayaka Koshibe16698a32014-09-13 22:19:02 -070095 int address = 0;
96 for (int i = 0; i < INET_LEN; i++) {
97 address |= octets[i] << ((INET_LEN - (i + 1)) * 8);
98 }
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -070099 return address;
100 }
101
102 @Override
103 public String toString() {
104 final StringBuilder builder = new StringBuilder();
105 for (final byte b : this.octets) {
106 if (builder.length() > 0) {
107 builder.append(".");
108 }
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700109 builder.append(String.format("%d", b));
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700110 }
111 return builder.toString();
112 }
113
114 @Override
115 public int hashCode() {
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700116 return Arrays.hashCode(octets);
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700117 }
118
119 @Override
120 public boolean equals(Object obj) {
Ayaka Koshibe50ee9242014-09-12 16:37:46 -0700121
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700122 if (obj instanceof IpAddress) {
123 IpAddress other = (IpAddress) obj;
Ayaka Koshibe50ee9242014-09-12 16:37:46 -0700124
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700125 if (this.version.equals(other.version)
126 && (Arrays.equals(this.octets, other.octets))) {
127 return true;
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700128 }
129 }
Ayaka Koshibe1a100982014-09-13 19:32:19 -0700130 return false;
Ayaka Koshibe1c7b38e2014-09-11 13:09:51 -0700131 }
132}