Toggle navigation
Toggle navigation
This project
Loading...
Sign in
홍길동
/
onos
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Ayaka Koshibe
2014-09-16 22:32:19 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
40e7fec52e5ed83830c3c2f8f62ff4ac1cb1a2b7
40e7fec5
1 parent
9842a4ef
netmask support in IpAddress
Change-Id: Ie5f4276a1fa1cdd56bebbd3cd1ee74ecacdab598
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
232 additions
and
45 deletions
utils/misc/src/main/java/org/onlab/packet/IpAddress.java
utils/misc/src/test/java/org/onlab/packet/IPAddressTest.java
utils/misc/src/main/java/org/onlab/packet/IpAddress.java
View file @
40e7fec
...
...
@@ -5,7 +5,7 @@ import java.util.Arrays;
/**
* A class representing an IPv4 address.
*/
public
class
IpAddress
{
public
final
class
IpAddress
{
//IP Versions
public
enum
Version
{
INET
,
INET6
};
...
...
@@ -14,13 +14,30 @@ public class IpAddress {
public
static
final
int
INET_LEN
=
4
;
public
static
final
int
INET6_LEN
=
16
;
//maximum CIDR value
public
static
final
int
MAX_INET_MASK
=
32
;
public
static
final
int
DEFAULT_MASK
=
0
;
/**
* Default value indicating an unspecified address.
*/
public
static
final
byte
[]
ANY
=
new
byte
[]
{
0
,
0
,
0
,
0
};
protected
Version
version
;
//does it make more sense to have a integral address?
protected
byte
[]
octets
;
protected
int
netmask
;
pr
otected
IpAddress
(
Version
ver
,
byte
[]
octets
)
{
pr
ivate
IpAddress
(
Version
ver
,
byte
[]
octets
,
int
netmask
)
{
this
.
version
=
ver
;
this
.
octets
=
Arrays
.
copyOf
(
octets
,
INET_LEN
);
this
.
netmask
=
netmask
;
}
private
IpAddress
(
Version
ver
,
byte
[]
octets
)
{
this
.
version
=
ver
;
this
.
octets
=
Arrays
.
copyOf
(
octets
,
INET_LEN
);
this
.
netmask
=
DEFAULT_MASK
;
}
/**
...
...
@@ -34,38 +51,87 @@ public class IpAddress {
}
/**
* Converts a
n integer into an IPv4
address.
* Converts a
byte array into an IP
address.
*
* @param address an integer representing an IP value
* @param address a byte array
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
public
static
IpAddress
valueOf
(
int
address
)
{
public
static
IpAddress
valueOf
(
byte
[]
address
,
int
netmask
)
{
return
new
IpAddress
(
Version
.
INET
,
address
,
netmask
);
}
/**
* Helper to convert an integer into a byte array.
*
* @param address the integer to convert
* @return a byte array
*/
private
static
byte
[]
bytes
(
int
address
)
{
byte
[]
bytes
=
new
byte
[
INET_LEN
];
for
(
int
i
=
0
;
i
<
INET_LEN
;
i
++)
{
bytes
[
i
]
=
(
byte
)
((
address
>>
(
INET_LEN
-
(
i
+
1
))
*
8
)
&
0xff
);
}
return
new
IpAddress
(
Version
.
INET
,
bytes
);
return
bytes
;
}
/**
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @return an IP address
*/
public
static
IpAddress
valueOf
(
int
address
)
{
return
new
IpAddress
(
Version
.
INET
,
bytes
(
address
));
}
/**
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
public
static
IpAddress
valueOf
(
int
address
,
int
netmask
)
{
return
new
IpAddress
(
Version
.
INET
,
bytes
(
address
),
netmask
);
}
/**
* Converts a
string in dotted-decimal notation (x.x.x.x) into
*
an IPv4 address
.
* Converts a
dotted-decimal string (x.x.x.x) into an IPv4 address. The
*
string can also be in CIDR (slash) notation
.
*
* @param address a
string representing an IP address, e.g. "10.0.0.1
"
* @param address a
IP address in string form, e.g. "10.0.0.1", "10.0.0.1/24
"
* @return an IP address
*/
public
static
IpAddress
valueOf
(
String
address
)
{
final
String
[]
parts
=
address
.
split
(
"\\."
);
if
(
parts
.
length
!=
INET_LEN
)
{
final
String
[]
parts
=
address
.
split
(
"\\/"
);
if
(
parts
.
length
>
2
)
{
throw
new
IllegalArgumentException
(
"Malformed IP address string; "
+
"Addres must take form \"x.x.x.x\" or \"x.x.x.x/y\""
);
}
int
mask
=
DEFAULT_MASK
;
if
(
parts
.
length
==
2
)
{
mask
=
Integer
.
valueOf
(
parts
[
1
]);
if
(
mask
>
MAX_INET_MASK
)
{
throw
new
IllegalArgumentException
(
"Value of subnet mask cannot exceed "
+
MAX_INET_MASK
);
}
}
final
String
[]
net
=
parts
[
0
].
split
(
"\\."
);
if
(
net
.
length
!=
INET_LEN
)
{
throw
new
IllegalArgumentException
(
"Malformed IP address string; "
+
"Addres must have four decimal values separated by dots (.)"
);
}
final
byte
[]
bytes
=
new
byte
[
INET_LEN
];
for
(
int
i
=
0
;
i
<
INET_LEN
;
i
++)
{
bytes
[
i
]
=
Byte
.
parseByte
(
parts
[
i
],
10
);
bytes
[
i
]
=
(
byte
)
Short
.
parseShort
(
net
[
i
],
10
);
}
return
new
IpAddress
(
Version
.
INET
,
bytes
);
return
new
IpAddress
(
Version
.
INET
,
bytes
,
mask
);
}
/**
...
...
@@ -99,34 +165,122 @@ public class IpAddress {
return
address
;
}
@Override
public
String
toString
()
{
final
StringBuilder
builder
=
new
StringBuilder
();
for
(
final
byte
b
:
this
.
octets
)
{
if
(
builder
.
length
()
>
0
)
{
builder
.
append
(
"."
);
/**
* Helper for computing the mask value from CIDR.
*
* @return an integer bitmask
*/
private
int
mask
()
{
int
shift
=
MAX_INET_MASK
-
this
.
netmask
;
return
((
Integer
.
MAX_VALUE
>>>
(
shift
-
1
))
<<
shift
);
}
builder
.
append
(
String
.
format
(
"%d"
,
b
));
/**
* Returns the subnet mask in IpAddress form. The netmask value for
* the returned IpAddress is 0, as the address itself is a mask.
*
* @return the subnet mask
*/
public
IpAddress
netmask
()
{
return
new
IpAddress
(
Version
.
INET
,
bytes
(
mask
()));
}
return
builder
.
toString
();
/**
* Returns the network portion of this address as an IpAddress.
* The netmask of the returned IpAddress is the current mask. If this
* address doesn't have a mask, this returns an all-0 IpAddress.
*
* @return the network address or null
*/
public
IpAddress
network
()
{
if
(
netmask
==
DEFAULT_MASK
)
{
return
new
IpAddress
(
version
,
ANY
,
DEFAULT_MASK
);
}
byte
[]
net
=
new
byte
[
4
];
byte
[]
mask
=
bytes
(
mask
());
for
(
int
i
=
0
;
i
<
INET_LEN
;
i
++)
{
net
[
i
]
=
(
byte
)
(
octets
[
i
]
&
mask
[
i
]);
}
return
new
IpAddress
(
version
,
net
,
netmask
);
}
/**
* Returns the host portion of the IPAddress, as an IPAddress.
* The netmask of the returned IpAddress is the current mask. If this
* address doesn't have a mask, this returns a copy of the current
* address.
*
* @return the host address
*/
public
IpAddress
host
()
{
if
(
netmask
==
DEFAULT_MASK
)
{
new
IpAddress
(
version
,
octets
,
netmask
);
}
byte
[]
host
=
new
byte
[
INET_LEN
];
byte
[]
mask
=
bytes
(
mask
());
for
(
int
i
=
0
;
i
<
INET_LEN
;
i
++)
{
host
[
i
]
=
(
byte
)
(
octets
[
i
]
&
~
mask
[
i
]);
}
return
new
IpAddress
(
version
,
host
,
netmask
);
}
@Override
public
int
hashCode
()
{
return
Arrays
.
hashCode
(
octets
);
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
netmask
;
result
=
prime
*
result
+
Arrays
.
hashCode
(
octets
);
result
=
prime
*
result
+
((
version
==
null
)
?
0
:
version
.
hashCode
());
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
instanceof
IpAddress
)
{
IpAddress
other
=
(
IpAddress
)
obj
;
if
(
this
.
version
.
equals
(
other
.
version
)
&&
(
Arrays
.
equals
(
this
.
octets
,
other
.
octets
)))
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
IpAddress
other
=
(
IpAddress
)
obj
;
if
(
netmask
!=
other
.
netmask
)
{
return
false
;
}
if
(!
Arrays
.
equals
(
octets
,
other
.
octets
))
{
return
false
;
}
if
(
version
!=
other
.
version
)
{
return
false
;
}
return
true
;
}
@Override
/*
* (non-Javadoc)
* format is "x.x.x.x" for non-masked (netmask 0) addresses,
* and "x.x.x.x/y" for masked addresses.
*
* @see java.lang.Object#toString()
*/
public
String
toString
()
{
final
StringBuilder
builder
=
new
StringBuilder
();
for
(
final
byte
b
:
this
.
octets
)
{
if
(
builder
.
length
()
>
0
)
{
builder
.
append
(
"."
);
}
builder
.
append
(
String
.
format
(
"%d"
,
b
&
0xff
));
}
if
(
netmask
!=
DEFAULT_MASK
)
{
builder
.
append
(
"/"
);
builder
.
append
(
String
.
format
(
"%d"
,
netmask
));
}
return
builder
.
toString
();
}
}
...
...
utils/misc/src/test/java/org/onlab/packet/IPAddressTest.java
View file @
40e7fec
package
org
.
onlab
.
packet
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.util.Arrays
;
...
...
@@ -11,33 +12,65 @@ import com.google.common.testing.EqualsTester;
public
class
IPAddressTest
{
private
static
final
byte
[]
BYTES1
=
new
byte
[]
{
0x0
,
0x0
,
0x0
,
0xa
};
private
static
final
byte
[]
BYTES2
=
new
byte
[]
{
0x0
,
0x0
,
0x0
,
0xb
};
private
static
final
int
INTVAL1
=
10
;
private
static
final
int
INTVAL2
=
12
;
private
static
final
String
STRVAL
=
"0.0.0.11"
;
private
static
final
byte
[]
BYTES1
=
new
byte
[]
{
0xa
,
0x0
,
0x0
,
0xa
};
private
static
final
byte
[]
BYTES2
=
new
byte
[]
{
0xa
,
0x0
,
0x0
,
0xb
};
private
static
final
int
INTVAL1
=
167772170
;
private
static
final
int
INTVAL2
=
167772171
;
private
static
final
String
STRVAL
=
"10.0.0.12"
;
private
static
final
int
MASK
=
16
;
@Test
public
void
testEquality
()
{
IpAddress
ip1
=
IpAddress
.
valueOf
(
BYTES1
);
IpAddress
ip2
=
IpAddress
.
valueOf
(
BYTES2
);
IpAddress
ip3
=
IpAddress
.
valueOf
(
INTVAL1
);
IpAddress
ip2
=
IpAddress
.
valueOf
(
INTVAL1
);
IpAddress
ip3
=
IpAddress
.
valueOf
(
BYTES2
);
IpAddress
ip4
=
IpAddress
.
valueOf
(
INTVAL2
);
IpAddress
ip5
=
IpAddress
.
valueOf
(
STRVAL
);
new
EqualsTester
().
addEqualityGroup
(
ip1
,
ip
3
)
.
addEqualityGroup
(
ip
2
,
ip5
)
.
addEqualityGroup
(
ip
4
)
new
EqualsTester
().
addEqualityGroup
(
ip1
,
ip
2
)
.
addEqualityGroup
(
ip
3
,
ip4
)
.
addEqualityGroup
(
ip
5
)
.
testEquals
();
// string conversions
IpAddress
ip6
=
IpAddress
.
valueOf
(
BYTES1
,
MASK
);
IpAddress
ip7
=
IpAddress
.
valueOf
(
"10.0.0.10/16"
);
IpAddress
ip8
=
IpAddress
.
valueOf
(
new
byte
[]
{
0xa
,
0x0
,
0x0
,
0xc
});
assertEquals
(
"incorrect address conversion"
,
ip6
,
ip7
);
assertEquals
(
"incorrect address conversion"
,
ip5
,
ip8
);
}
@Test
public
void
basics
()
{
IpAddress
ip4
=
IpAddress
.
valueOf
(
BYTES1
);
assertEquals
(
"incorrect IP Version"
,
Version
.
INET
,
ip4
.
version
());
assertEquals
(
"faulty toOctets()"
,
Arrays
.
equals
(
new
byte
[]
{
0x0
,
0x0
,
0x0
,
0xa
},
ip4
.
toOctets
()),
true
);
assertEquals
(
"faulty toInt()"
,
INTVAL1
,
ip4
.
toInt
());
assertEquals
(
"faulty toString()"
,
"0.0.0.10"
,
ip4
.
toString
());
IpAddress
ip1
=
IpAddress
.
valueOf
(
BYTES1
,
MASK
);
final
byte
[]
bytes
=
new
byte
[]
{
0xa
,
0x0
,
0x0
,
0xa
};
//check fields
assertEquals
(
"incorrect IP Version"
,
Version
.
INET
,
ip1
.
version
());
assertEquals
(
"incorrect netmask"
,
16
,
ip1
.
netmask
);
assertTrue
(
"faulty toOctets()"
,
Arrays
.
equals
(
bytes
,
ip1
.
toOctets
()));
assertEquals
(
"faulty toInt()"
,
INTVAL1
,
ip1
.
toInt
());
assertEquals
(
"faulty toString()"
,
"10.0.0.10/16"
,
ip1
.
toString
());
}
@Test
public
void
netmasks
()
{
// masked
IpAddress
ip1
=
IpAddress
.
valueOf
(
BYTES1
,
MASK
);
IpAddress
host
=
IpAddress
.
valueOf
(
"0.0.0.10/16"
);
IpAddress
network
=
IpAddress
.
valueOf
(
"10.0.0.0/16"
);
assertEquals
(
"incorrect host address"
,
host
,
ip1
.
host
());
assertEquals
(
"incorrect network address"
,
network
,
ip1
.
network
());
assertEquals
(
"incorrect netmask"
,
"255.255.0.0"
,
ip1
.
netmask
().
toString
());
//unmasked
IpAddress
ip2
=
IpAddress
.
valueOf
(
BYTES1
);
IpAddress
umhost
=
IpAddress
.
valueOf
(
"10.0.0.10/0"
);
IpAddress
umnet
=
IpAddress
.
valueOf
(
"0.0.0.0/0"
);
assertEquals
(
"incorrect host address"
,
umhost
,
ip2
.
host
());
assertEquals
(
"incorrect host address"
,
umnet
,
ip2
.
network
());
assertTrue
(
"incorrect netmask"
,
Arrays
.
equals
(
IpAddress
.
ANY
,
ip2
.
netmask
().
toOctets
()));
}
}
...
...
Please
register
or
login
to post a comment