Jonathan Hart

Wired up HostMonitor to its dependencies and got it working.

...@@ -3,8 +3,6 @@ package org.onlab.onos.config; ...@@ -3,8 +3,6 @@ package org.onlab.onos.config;
3 import java.util.List; 3 import java.util.List;
4 4
5 import org.codehaus.jackson.annotate.JsonProperty; 5 import org.codehaus.jackson.annotate.JsonProperty;
6 -import org.onlab.packet.IpPrefix;
7 -import org.onlab.packet.MacAddress;
8 6
9 /** 7 /**
10 * Represents a set of addresses bound to a port. 8 * Represents a set of addresses bound to a port.
...@@ -12,8 +10,8 @@ import org.onlab.packet.MacAddress; ...@@ -12,8 +10,8 @@ import org.onlab.packet.MacAddress;
12 public class AddressEntry { 10 public class AddressEntry {
13 private String dpid; 11 private String dpid;
14 private short portNumber; 12 private short portNumber;
15 - private List<IpPrefix> ipAddresses; 13 + private List<String> ipAddresses;
16 - private MacAddress macAddress; 14 + private String macAddress;
17 15
18 public String getDpid() { 16 public String getDpid() {
19 return dpid; 17 return dpid;
...@@ -33,21 +31,21 @@ public class AddressEntry { ...@@ -33,21 +31,21 @@ public class AddressEntry {
33 this.portNumber = portNumber; 31 this.portNumber = portNumber;
34 } 32 }
35 33
36 - public List<IpPrefix> getIpAddresses() { 34 + public List<String> getIpAddresses() {
37 return ipAddresses; 35 return ipAddresses;
38 } 36 }
39 37
40 @JsonProperty("ips") 38 @JsonProperty("ips")
41 - public void setIpAddresses(List<IpPrefix> ipAddresses) { 39 + public void setIpAddresses(List<String> strIps) {
42 - this.ipAddresses = ipAddresses; 40 + this.ipAddresses = strIps;
43 } 41 }
44 42
45 - public MacAddress getMacAddress() { 43 + public String getMacAddress() {
46 return macAddress; 44 return macAddress;
47 } 45 }
48 46
49 @JsonProperty("mac") 47 @JsonProperty("mac")
50 - public void setMacAddress(MacAddress macAddress) { 48 + public void setMacAddress(String macAddress) {
51 this.macAddress = macAddress; 49 this.macAddress = macAddress;
52 } 50 }
53 } 51 }
......
...@@ -5,6 +5,8 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,8 @@ import static org.slf4j.LoggerFactory.getLogger;
5 import java.io.File; 5 import java.io.File;
6 import java.io.FileNotFoundException; 6 import java.io.FileNotFoundException;
7 import java.io.IOException; 7 import java.io.IOException;
8 +import java.util.HashSet;
9 +import java.util.Set;
8 10
9 import org.apache.felix.scr.annotations.Activate; 11 import org.apache.felix.scr.annotations.Activate;
10 import org.apache.felix.scr.annotations.Component; 12 import org.apache.felix.scr.annotations.Component;
...@@ -17,10 +19,10 @@ import org.onlab.onos.net.DeviceId; ...@@ -17,10 +19,10 @@ import org.onlab.onos.net.DeviceId;
17 import org.onlab.onos.net.PortNumber; 19 import org.onlab.onos.net.PortNumber;
18 import org.onlab.onos.net.host.HostAdminService; 20 import org.onlab.onos.net.host.HostAdminService;
19 import org.onlab.onos.net.host.PortAddresses; 21 import org.onlab.onos.net.host.PortAddresses;
22 +import org.onlab.packet.IpPrefix;
23 +import org.onlab.packet.MacAddress;
20 import org.slf4j.Logger; 24 import org.slf4j.Logger;
21 25
22 -import com.google.common.collect.Sets;
23 -
24 /** 26 /**
25 * Simple configuration module to read in supplementary network configuration 27 * Simple configuration module to read in supplementary network configuration
26 * from a file. 28 * from a file.
...@@ -51,9 +53,29 @@ public class NetworkConfigReader { ...@@ -51,9 +53,29 @@ public class NetworkConfigReader {
51 DeviceId.deviceId(dpidToUri(entry.getDpid())), 53 DeviceId.deviceId(dpidToUri(entry.getDpid())),
52 PortNumber.portNumber(entry.getPortNumber())); 54 PortNumber.portNumber(entry.getPortNumber()));
53 55
54 - PortAddresses addresses = new PortAddresses(cp, 56 + Set<IpPrefix> ipAddresses = new HashSet<IpPrefix>();
55 - Sets.newHashSet(entry.getIpAddresses()), 57 +
58 + for (String strIp : entry.getIpAddresses()) {
59 + try {
60 + IpPrefix address = IpPrefix.valueOf(strIp);
61 + ipAddresses.add(address);
62 + } catch (IllegalArgumentException e) {
63 + log.warn("Bad format for IP address in config: {}", strIp);
64 + }
65 + }
66 +
67 + MacAddress macAddress = null;
68 + if (entry.getMacAddress() != null) {
69 + try {
70 + macAddress = MacAddress.valueOf(entry.getMacAddress());
71 + } catch (IllegalArgumentException e) {
72 + log.warn("Bad format for MAC address in config: {}",
56 entry.getMacAddress()); 73 entry.getMacAddress());
74 + }
75 + }
76 +
77 + PortAddresses addresses = new PortAddresses(cp,
78 + ipAddresses, macAddress);
57 79
58 hostAdminService.bindAddressesToPort(addresses); 80 hostAdminService.bindAddressesToPort(addresses);
59 } 81 }
......
1 package org.onlab.onos.net.host.impl; 1 package org.onlab.onos.net.host.impl;
2 2
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +import static org.slf4j.LoggerFactory.getLogger;
5 +
6 +import java.util.Set;
7 +
3 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -12,6 +17,7 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -12,6 +17,7 @@ import org.onlab.onos.net.ConnectPoint;
12 import org.onlab.onos.net.DeviceId; 17 import org.onlab.onos.net.DeviceId;
13 import org.onlab.onos.net.Host; 18 import org.onlab.onos.net.Host;
14 import org.onlab.onos.net.HostId; 19 import org.onlab.onos.net.HostId;
20 +import org.onlab.onos.net.device.DeviceService;
15 import org.onlab.onos.net.host.HostAdminService; 21 import org.onlab.onos.net.host.HostAdminService;
16 import org.onlab.onos.net.host.HostDescription; 22 import org.onlab.onos.net.host.HostDescription;
17 import org.onlab.onos.net.host.HostEvent; 23 import org.onlab.onos.net.host.HostEvent;
...@@ -23,6 +29,7 @@ import org.onlab.onos.net.host.HostService; ...@@ -23,6 +29,7 @@ import org.onlab.onos.net.host.HostService;
23 import org.onlab.onos.net.host.HostStore; 29 import org.onlab.onos.net.host.HostStore;
24 import org.onlab.onos.net.host.HostStoreDelegate; 30 import org.onlab.onos.net.host.HostStoreDelegate;
25 import org.onlab.onos.net.host.PortAddresses; 31 import org.onlab.onos.net.host.PortAddresses;
32 +import org.onlab.onos.net.packet.PacketService;
26 import org.onlab.onos.net.provider.AbstractProviderRegistry; 33 import org.onlab.onos.net.provider.AbstractProviderRegistry;
27 import org.onlab.onos.net.provider.AbstractProviderService; 34 import org.onlab.onos.net.provider.AbstractProviderService;
28 import org.onlab.packet.IpAddress; 35 import org.onlab.packet.IpAddress;
...@@ -31,11 +38,6 @@ import org.onlab.packet.MacAddress; ...@@ -31,11 +38,6 @@ import org.onlab.packet.MacAddress;
31 import org.onlab.packet.VlanId; 38 import org.onlab.packet.VlanId;
32 import org.slf4j.Logger; 39 import org.slf4j.Logger;
33 40
34 -import java.util.Set;
35 -
36 -import static com.google.common.base.Preconditions.checkNotNull;
37 -import static org.slf4j.LoggerFactory.getLogger;
38 -
39 /** 41 /**
40 * Provides basic implementation of the host SB &amp; NB APIs. 42 * Provides basic implementation of the host SB &amp; NB APIs.
41 */ 43 */
...@@ -59,12 +61,22 @@ public class HostManager ...@@ -59,12 +61,22 @@ public class HostManager
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected EventDeliveryService eventDispatcher; 62 protected EventDeliveryService eventDispatcher;
61 63
64 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 + protected DeviceService deviceService;
66 +
67 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 + protected PacketService packetService;
69 +
70 + private HostMonitor monitor;
62 71
63 @Activate 72 @Activate
64 public void activate() { 73 public void activate() {
74 + log.info("Started");
65 store.setDelegate(delegate); 75 store.setDelegate(delegate);
66 eventDispatcher.addSink(HostEvent.class, listenerRegistry); 76 eventDispatcher.addSink(HostEvent.class, listenerRegistry);
67 - log.info("Started"); 77 +
78 + monitor = new HostMonitor(deviceService, packetService, this);
79 +
68 } 80 }
69 81
70 @Deactivate 82 @Deactivate
...@@ -76,6 +88,8 @@ public class HostManager ...@@ -76,6 +88,8 @@ public class HostManager
76 88
77 @Override 89 @Override
78 protected HostProviderService createProviderService(HostProvider provider) { 90 protected HostProviderService createProviderService(HostProvider provider) {
91 + monitor.registerHostProvider(provider);
92 +
79 return new InternalHostProviderService(provider); 93 return new InternalHostProviderService(provider);
80 } 94 }
81 95
...@@ -126,12 +140,12 @@ public class HostManager ...@@ -126,12 +140,12 @@ public class HostManager
126 140
127 @Override 141 @Override
128 public void startMonitoringIp(IpAddress ip) { 142 public void startMonitoringIp(IpAddress ip) {
129 - // TODO pass through to HostMonitor 143 + monitor.addMonitoringFor(ip);
130 } 144 }
131 145
132 @Override 146 @Override
133 public void stopMonitoringIp(IpAddress ip) { 147 public void stopMonitoringIp(IpAddress ip) {
134 - // TODO pass through to HostMonitor 148 + monitor.stopMonitoring(ip);
135 } 149 }
136 150
137 @Override 151 @Override
......
...@@ -2,10 +2,11 @@ package org.onlab.onos.net.host.impl; ...@@ -2,10 +2,11 @@ package org.onlab.onos.net.host.impl;
2 2
3 import java.nio.ByteBuffer; 3 import java.nio.ByteBuffer;
4 import java.util.ArrayList; 4 import java.util.ArrayList;
5 -import java.util.Collections;
6 import java.util.HashSet; 5 import java.util.HashSet;
7 import java.util.List; 6 import java.util.List;
7 +import java.util.Map;
8 import java.util.Set; 8 import java.util.Set;
9 +import java.util.concurrent.ConcurrentHashMap;
9 import java.util.concurrent.TimeUnit; 10 import java.util.concurrent.TimeUnit;
10 11
11 import org.jboss.netty.util.Timeout; 12 import org.jboss.netty.util.Timeout;
...@@ -21,19 +22,19 @@ import org.onlab.onos.net.flow.TrafficTreatment; ...@@ -21,19 +22,19 @@ import org.onlab.onos.net.flow.TrafficTreatment;
21 import org.onlab.onos.net.flow.instructions.Instruction; 22 import org.onlab.onos.net.flow.instructions.Instruction;
22 import org.onlab.onos.net.flow.instructions.Instructions; 23 import org.onlab.onos.net.flow.instructions.Instructions;
23 import org.onlab.onos.net.host.HostProvider; 24 import org.onlab.onos.net.host.HostProvider;
24 -import org.onlab.onos.net.host.HostService;
25 -import org.onlab.onos.net.host.HostStore;
26 import org.onlab.onos.net.host.PortAddresses; 25 import org.onlab.onos.net.host.PortAddresses;
27 import org.onlab.onos.net.packet.DefaultOutboundPacket; 26 import org.onlab.onos.net.packet.DefaultOutboundPacket;
28 import org.onlab.onos.net.packet.OutboundPacket; 27 import org.onlab.onos.net.packet.OutboundPacket;
29 import org.onlab.onos.net.packet.PacketService; 28 import org.onlab.onos.net.packet.PacketService;
30 -import org.onlab.onos.net.topology.TopologyService; 29 +import org.onlab.onos.net.provider.ProviderId;
31 import org.onlab.packet.ARP; 30 import org.onlab.packet.ARP;
32 import org.onlab.packet.Ethernet; 31 import org.onlab.packet.Ethernet;
33 import org.onlab.packet.IpAddress; 32 import org.onlab.packet.IpAddress;
34 import org.onlab.packet.IpPrefix; 33 import org.onlab.packet.IpPrefix;
35 import org.onlab.packet.MacAddress; 34 import org.onlab.packet.MacAddress;
36 import org.onlab.util.Timer; 35 import org.onlab.util.Timer;
36 +import org.slf4j.Logger;
37 +import org.slf4j.LoggerFactory;
37 38
38 /** 39 /**
39 * Monitors hosts on the dataplane to detect changes in host data. 40 * Monitors hosts on the dataplane to detect changes in host data.
...@@ -43,9 +44,7 @@ import org.onlab.util.Timer; ...@@ -43,9 +44,7 @@ import org.onlab.util.Timer;
43 * probe for hosts that have not yet been detected (specified by IP address). 44 * probe for hosts that have not yet been detected (specified by IP address).
44 */ 45 */
45 public class HostMonitor implements TimerTask { 46 public class HostMonitor implements TimerTask {
46 - 47 + private static final Logger log = LoggerFactory.getLogger(HostMonitor.class);
47 - private static final byte[] DEFAULT_MAC_ADDRESS =
48 - MacAddress.valueOf("00:00:00:00:00:01").getAddress();
49 48
50 private static final byte[] ZERO_MAC_ADDRESS = 49 private static final byte[] ZERO_MAC_ADDRESS =
51 MacAddress.valueOf("00:00:00:00:00:00").getAddress(); 50 MacAddress.valueOf("00:00:00:00:00:00").getAddress();
...@@ -54,59 +53,77 @@ public class HostMonitor implements TimerTask { ...@@ -54,59 +53,77 @@ public class HostMonitor implements TimerTask {
54 private static final byte[] BROADCAST_MAC = 53 private static final byte[] BROADCAST_MAC =
55 MacAddress.valueOf("ff:ff:ff:ff:ff:ff").getAddress(); 54 MacAddress.valueOf("ff:ff:ff:ff:ff:ff").getAddress();
56 55
57 - private final HostService hostService; 56 + private DeviceService deviceService;
58 - private final TopologyService topologyService; 57 + private PacketService packetService;
59 - private final DeviceService deviceService; 58 + private HostManager hostManager;
60 - private final HostProvider hostProvider;
61 - private final PacketService packetService;
62 - private final HostStore hostStore;
63 59
64 private final Set<IpAddress> monitoredAddresses; 60 private final Set<IpAddress> monitoredAddresses;
65 61
62 + private final Map<ProviderId, HostProvider> hostProviders;
63 +
66 private final long probeRate; 64 private final long probeRate;
67 65
68 private final Timeout timeout; 66 private final Timeout timeout;
69 67
70 - public HostMonitor(HostService hostService, TopologyService topologyService, 68 + public HostMonitor(
71 DeviceService deviceService, 69 DeviceService deviceService,
72 - HostProvider hostProvider, PacketService packetService, 70 + PacketService packetService,
73 - HostStore hostStore) { 71 + HostManager hostService) {
74 - this.hostService = hostService; 72 +
75 - this.topologyService = topologyService;
76 this.deviceService = deviceService; 73 this.deviceService = deviceService;
77 - this.hostProvider = hostProvider;
78 this.packetService = packetService; 74 this.packetService = packetService;
79 - this.hostStore = hostStore; 75 + this.hostManager = hostService;
80 76
81 monitoredAddresses = new HashSet<>(); 77 monitoredAddresses = new HashSet<>();
78 + hostProviders = new ConcurrentHashMap<>();
82 79
83 probeRate = 30000; // milliseconds 80 probeRate = 30000; // milliseconds
84 81
85 timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS); 82 timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS);
83 +
84 + addDefaultAddresses();
86 } 85 }
87 86
88 - public void addMonitoringFor(IpAddress ip) { 87 + private void addDefaultAddresses() {
88 + //monitoredAddresses.add(IpAddress.valueOf("10.0.0.1"));
89 + }
90 +
91 + void addMonitoringFor(IpAddress ip) {
89 monitoredAddresses.add(ip); 92 monitoredAddresses.add(ip);
90 } 93 }
91 94
92 - public void stopMonitoring(IpAddress ip) { 95 + void stopMonitoring(IpAddress ip) {
93 monitoredAddresses.remove(ip); 96 monitoredAddresses.remove(ip);
94 } 97 }
95 98
96 - public void shutdown() { 99 + void shutdown() {
97 timeout.cancel(); 100 timeout.cancel();
98 } 101 }
99 102
103 + void registerHostProvider(HostProvider provider) {
104 + hostProviders.put(provider.id(), provider);
105 + }
106 +
107 + void unregisterHostProvider(HostProvider provider) {
108 + // TODO find out how to call this
109 + }
110 +
100 @Override 111 @Override
101 public void run(Timeout timeout) throws Exception { 112 public void run(Timeout timeout) throws Exception {
102 for (IpAddress ip : monitoredAddresses) { 113 for (IpAddress ip : monitoredAddresses) {
103 - Set<Host> hosts = Collections.emptySet(); //TODO hostService.getHostsByIp(ip); 114 + // TODO have to convert right now because the HostService API uses IpPrefix
115 + IpPrefix prefix = IpPrefix.valueOf(ip.toOctets());
116 +
117 + Set<Host> hosts = hostManager.getHostsByIp(prefix);
104 118
105 if (hosts.isEmpty()) { 119 if (hosts.isEmpty()) {
106 sendArpRequest(ip); 120 sendArpRequest(ip);
107 } else { 121 } else {
108 for (Host host : hosts) { 122 for (Host host : hosts) {
109 - hostProvider.triggerProbe(host); 123 + HostProvider provider = hostProviders.get(host.providerId());
124 + if (provider != null) {
125 + provider.triggerProbe(host);
126 + }
110 } 127 }
111 } 128 }
112 } 129 }
...@@ -120,29 +137,26 @@ public class HostMonitor implements TimerTask { ...@@ -120,29 +137,26 @@ public class HostMonitor implements TimerTask {
120 * @param targetIp IP address to ARP for 137 * @param targetIp IP address to ARP for
121 */ 138 */
122 private void sendArpRequest(IpAddress targetIp) { 139 private void sendArpRequest(IpAddress targetIp) {
123 -
124 // Find ports with an IP address in the target's subnet and sent ARP 140 // Find ports with an IP address in the target's subnet and sent ARP
125 // probes out those ports. 141 // probes out those ports.
126 for (Device device : deviceService.getDevices()) { 142 for (Device device : deviceService.getDevices()) {
127 for (Port port : deviceService.getPorts(device.id())) { 143 for (Port port : deviceService.getPorts(device.id())) {
128 ConnectPoint cp = new ConnectPoint(device.id(), port.number()); 144 ConnectPoint cp = new ConnectPoint(device.id(), port.number());
129 - PortAddresses addresses = hostStore.getAddressBindingsForPort(cp); 145 + PortAddresses addresses = hostManager.getAddressBindingsForPort(cp);
130 146
131 - /*for (IpPrefix prefix : addresses.ips()) { 147 + for (IpPrefix prefix : addresses.ips()) {
132 if (prefix.contains(targetIp)) { 148 if (prefix.contains(targetIp)) {
133 - sendProbe(device.id(), port, addresses, targetIp); 149 + sendProbe(device.id(), port, targetIp,
150 + prefix.toIpAddress(), addresses.mac());
151 + }
134 } 152 }
135 - }*/
136 } 153 }
137 } 154 }
138 -
139 - // TODO case where no address was found.
140 - // Broadcast out internal edge ports?
141 } 155 }
142 156
143 - private void sendProbe(DeviceId deviceId, Port port, PortAddresses portAddresses, 157 + private void sendProbe(DeviceId deviceId, Port port, IpAddress targetIp,
144 - IpAddress targetIp) { 158 + IpAddress sourceIp, MacAddress sourceMac) {
145 - Ethernet arpPacket = createArpFor(targetIp, portAddresses); 159 + Ethernet arpPacket = buildArpRequest(targetIp, sourceIp, sourceMac);
146 160
147 List<Instruction> instructions = new ArrayList<>(); 161 List<Instruction> instructions = new ArrayList<>();
148 instructions.add(Instructions.createOutput(port.number())); 162 instructions.add(Instructions.createOutput(port.number()));
...@@ -158,30 +172,25 @@ public class HostMonitor implements TimerTask { ...@@ -158,30 +172,25 @@ public class HostMonitor implements TimerTask {
158 packetService.emit(outboundPacket); 172 packetService.emit(outboundPacket);
159 } 173 }
160 174
161 - private Ethernet createArpFor(IpAddress targetIp, PortAddresses portAddresses) { 175 + private Ethernet buildArpRequest(IpAddress targetIp, IpAddress sourceIp,
176 + MacAddress sourceMac) {
162 177
163 ARP arp = new ARP(); 178 ARP arp = new ARP();
164 arp.setHardwareType(ARP.HW_TYPE_ETHERNET) 179 arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
165 .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH) 180 .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
166 .setProtocolType(ARP.PROTO_TYPE_IP) 181 .setProtocolType(ARP.PROTO_TYPE_IP)
167 - .setProtocolAddressLength((byte) IpPrefix.INET_LEN); 182 + .setProtocolAddressLength((byte) IpPrefix.INET_LEN)
168 - 183 + .setOpCode(ARP.OP_REQUEST);
169 - byte[] sourceMacAddress;
170 - if (portAddresses.mac() == null) {
171 - sourceMacAddress = DEFAULT_MAC_ADDRESS;
172 - } else {
173 - sourceMacAddress = portAddresses.mac().getAddress();
174 - }
175 184
176 - arp.setSenderHardwareAddress(sourceMacAddress) 185 + arp.setSenderHardwareAddress(sourceMac.getAddress())
177 - //TODO .setSenderProtocolAddress(portAddresses.ips().toOctets()) 186 + .setSenderProtocolAddress(sourceIp.toOctets())
178 .setTargetHardwareAddress(ZERO_MAC_ADDRESS) 187 .setTargetHardwareAddress(ZERO_MAC_ADDRESS)
179 .setTargetProtocolAddress(targetIp.toOctets()); 188 .setTargetProtocolAddress(targetIp.toOctets());
180 189
181 Ethernet ethernet = new Ethernet(); 190 Ethernet ethernet = new Ethernet();
182 ethernet.setEtherType(Ethernet.TYPE_ARP) 191 ethernet.setEtherType(Ethernet.TYPE_ARP)
183 .setDestinationMACAddress(BROADCAST_MAC) 192 .setDestinationMACAddress(BROADCAST_MAC)
184 - .setSourceMACAddress(sourceMacAddress) 193 + .setSourceMACAddress(sourceMac.getAddress())
185 .setPayload(arp); 194 .setPayload(arp);
186 195
187 return ethernet; 196 return ethernet;
......
...@@ -250,6 +250,17 @@ public final class IpPrefix { ...@@ -250,6 +250,17 @@ public final class IpPrefix {
250 return new IpPrefix(version, host, netmask); 250 return new IpPrefix(version, host, netmask);
251 } 251 }
252 252
253 + /**
254 + * Returns an IpAddress of the bytes contained in this prefix.
255 + * FIXME this is a hack for now and only works because IpPrefix doesn't
256 + * mask the input bytes on creation.
257 + *
258 + * @return the IpAddress
259 + */
260 + public IpAddress toIpAddress() {
261 + return IpAddress.valueOf(octets);
262 + }
263 +
253 public boolean isMasked() { 264 public boolean isMasked() {
254 return mask() != 0; 265 return mask() != 0;
255 } 266 }
...@@ -278,6 +289,17 @@ public final class IpPrefix { ...@@ -278,6 +289,17 @@ public final class IpPrefix {
278 return false; 289 return false;
279 } 290 }
280 291
292 + public boolean contains(IpAddress address) {
293 + // Need to get the network address because prefixes aren't automatically
294 + // masked on creation
295 + IpPrefix meMasked = network();
296 +
297 + IpPrefix otherMasked =
298 + IpPrefix.valueOf(address.octets, netmask).network();
299 +
300 + return Arrays.equals(meMasked.octets, otherMasked.octets);
301 + }
302 +
281 @Override 303 @Override
282 public int hashCode() { 304 public int hashCode() {
283 final int prime = 31; 305 final int prime = 31;
...@@ -303,6 +325,7 @@ public final class IpPrefix { ...@@ -303,6 +325,7 @@ public final class IpPrefix {
303 if (netmask != other.netmask) { 325 if (netmask != other.netmask) {
304 return false; 326 return false;
305 } 327 }
328 + // TODO not quite right until we mask the input
306 if (!Arrays.equals(octets, other.octets)) { 329 if (!Arrays.equals(octets, other.octets)) {
307 return false; 330 return false;
308 } 331 }
......
...@@ -76,7 +76,7 @@ public class IpPrefixTest { ...@@ -76,7 +76,7 @@ public class IpPrefixTest {
76 } 76 }
77 77
78 @Test 78 @Test
79 - public void testContains() { 79 + public void testContainsIpPrefix() {
80 IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31); 80 IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31);
81 IpPrefix slash32 = IpPrefix.valueOf(BYTES1, 32); 81 IpPrefix slash32 = IpPrefix.valueOf(BYTES1, 32);
82 IpPrefix differentSlash32 = IpPrefix.valueOf(BYTES2, 32); 82 IpPrefix differentSlash32 = IpPrefix.valueOf(BYTES2, 32);
...@@ -96,4 +96,17 @@ public class IpPrefixTest { ...@@ -96,4 +96,17 @@ public class IpPrefixTest {
96 assertTrue(slash8.contains(slash31)); 96 assertTrue(slash8.contains(slash31));
97 assertFalse(slash31.contains(slash8)); 97 assertFalse(slash31.contains(slash8));
98 } 98 }
99 +
100 + @Test
101 + public void testContainsIpAddress() {
102 + IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31);
103 + IpAddress slash32 = IpAddress.valueOf(BYTES1, 32);
104 +
105 + assertTrue(slash31.contains(slash32));
106 +
107 + IpPrefix intf = IpPrefix.valueOf("192.168.10.101/24");
108 + IpAddress addr = IpAddress.valueOf("192.168.10.1");
109 +
110 + assertTrue(intf.contains(addr));
111 + }
99 } 112 }
......