33import static org .pcap4j .util .ByteArrays .BYTE_SIZE_IN_BYTES ;
44
55import com .cisco .trex .stateless .exception .ServiceModeRequiredException ;
6- import com .cisco .trex .stateless .model .*;
6+ import com .cisco .trex .stateless .model .Ipv6Node ;
7+ import com .cisco .trex .stateless .model .PortStatus ;
8+ import com .cisco .trex .stateless .model .StreamMode ;
9+ import com .cisco .trex .stateless .model .StreamModeRate ;
10+ import com .cisco .trex .stateless .model .StreamRxStats ;
11+ import com .cisco .trex .stateless .model .StreamVM ;
12+ import com .cisco .trex .stateless .model .TRexClientResult ;
713import com .google .common .net .InetAddresses ;
814import java .net .Inet6Address ;
915import java .net .UnknownHostException ;
10- import java .util .*;
16+ import java .util .ArrayList ;
17+ import java .util .Arrays ;
18+ import java .util .Collections ;
19+ import java .util .HashMap ;
20+ import java .util .List ;
21+ import java .util .Map ;
22+ import java .util .Optional ;
1123import java .util .function .Predicate ;
1224import java .util .stream .Collectors ;
1325import java .util .stream .Stream ;
1426import org .apache .commons .lang3 .StringUtils ;
15- import org .pcap4j .packet .*;
27+ import org .pcap4j .packet .EthernetPacket ;
28+ import org .pcap4j .packet .IcmpV6CommonPacket ;
1629import org .pcap4j .packet .IcmpV6CommonPacket .IpV6NeighborDiscoveryOption ;
30+ import org .pcap4j .packet .IcmpV6EchoReplyPacket ;
31+ import org .pcap4j .packet .IcmpV6EchoRequestPacket ;
32+ import org .pcap4j .packet .IcmpV6NeighborAdvertisementPacket ;
1733import org .pcap4j .packet .IcmpV6NeighborAdvertisementPacket .IcmpV6NeighborAdvertisementHeader ;
18- import org .pcap4j .packet .namednumber .*;
34+ import org .pcap4j .packet .IcmpV6NeighborSolicitationPacket ;
35+ import org .pcap4j .packet .IpV6NeighborDiscoverySourceLinkLayerAddressOption ;
36+ import org .pcap4j .packet .IpV6NeighborDiscoveryTargetLinkLayerAddressOption ;
37+ import org .pcap4j .packet .IpV6Packet ;
38+ import org .pcap4j .packet .IpV6SimpleFlowLabel ;
39+ import org .pcap4j .packet .IpV6SimpleTrafficClass ;
40+ import org .pcap4j .packet .Packet ;
41+ import org .pcap4j .packet .namednumber .EtherType ;
42+ import org .pcap4j .packet .namednumber .IcmpV6Code ;
43+ import org .pcap4j .packet .namednumber .IcmpV6Type ;
44+ import org .pcap4j .packet .namednumber .IpNumber ;
45+ import org .pcap4j .packet .namednumber .IpVersion ;
1946import org .pcap4j .util .ByteArrays ;
2047import org .pcap4j .util .MacAddress ;
21- import org .slf4j .Logger ;
22- import org .slf4j .LoggerFactory ;
2348
2449public class IPv6NeighborDiscoveryService {
2550
26- private static final Logger LOGGER = LoggerFactory .getLogger (IPv6NeighborDiscoveryService .class );
27-
2851 private TRexClient tRexClient ;
2952 private String srcMac ;
30- private long endTs ;
3153
3254 public IPv6NeighborDiscoveryService (TRexClient tRexClient ) {
3355 this .tRexClient = tRexClient ;
@@ -37,7 +59,7 @@ public Map<String, Ipv6Node> scan(int portIdx, int timeDuration, String dstIP, S
3759 throws ServiceModeRequiredException {
3860 String broadcastIP = "ff02::1" ;
3961
40- long endTs = System .currentTimeMillis () + timeDuration / 2 * 1000 ;
62+ long endTimeSec = System .currentTimeMillis () + timeDuration / 2 * 1000 ;
4163 TRexClientResult <PortStatus > portStatusResult = tRexClient .getPortStatus (portIdx );
4264 PortStatus portStatus = portStatusResult .get ();
4365
@@ -61,7 +83,7 @@ public Map<String, Ipv6Node> scan(int portIdx, int timeDuration, String dstIP, S
6183 etherPkt .contains (IcmpV6NeighborSolicitationPacket .class )
6284 || etherPkt .contains (IcmpV6NeighborAdvertisementPacket .class );
6385
64- while (endTs > System .currentTimeMillis ()) {
86+ while (endTimeSec > System .currentTimeMillis ()) {
6587 tRexClient
6688 .getRxQueue (portIdx , ipV6NSPktFilter )
6789 .forEach (
@@ -81,8 +103,8 @@ public Map<String, Ipv6Node> scan(int portIdx, int timeDuration, String dstIP, S
81103
82104 Predicate <EthernetPacket > ipV6NAPktFilter =
83105 etherPkt -> etherPkt .contains (IcmpV6NeighborAdvertisementPacket .class );
84- endTs = System .currentTimeMillis () + timeDuration / 2 * 1000 ;
85- while (endTs > System .currentTimeMillis ()) {
106+ endTimeSec = System .currentTimeMillis () + timeDuration / 2 * 1000 ;
107+ while (endTimeSec > System .currentTimeMillis ()) {
86108 icmpNAReplies .addAll (tRexClient .getRxQueue (portIdx , ipV6NAPktFilter ));
87109 }
88110 tRexClient .removeRxQueue (portIdx );
@@ -111,8 +133,7 @@ private Ipv6Node toIpv6Node(EthernetPacket ethernetPacket) {
111133 }
112134
113135 public EthernetPacket sendIcmpV6Echo (
114- int portIdx , String dstIp , int icmpId , int icmpSeq , int timeOut )
115- throws ServiceModeRequiredException {
136+ int portIdx , String dstIp , int icmpId , int icmpSeq , int timeOut ) {
116137 Map <String , EthernetPacket > stringEthernetPacketMap =
117138 sendNSandIcmpV6Req (portIdx , timeOut , dstIp );
118139
@@ -126,9 +147,9 @@ public EthernetPacket sendIcmpV6Echo(
126147 String nodeMac = etherPkt .getHeader ().getSrcAddr ().toString ();
127148 Packet pingPkt = buildICMPV6EchoReq (null , srcMac , nodeMac , dstIp , icmpId , icmpSeq );
128149 tRexClient .startStreamsIntermediate (portIdx , Arrays .asList (buildStream (pingPkt )));
129- long endTs = System .currentTimeMillis () + timeOut * 1000 / 2 ;
150+ long endTimeSec = System .currentTimeMillis () + timeOut * 1000 / 2 ;
130151
131- while (endTs > System .currentTimeMillis ()) {
152+ while (endTimeSec > System .currentTimeMillis ()) {
132153 List <EthernetPacket > rxQueue =
133154 tRexClient .getRxQueue (portIdx , pkt -> pkt .contains (IcmpV6EchoReplyPacket .class ));
134155 if (rxQueue .size () > 0 ) {
@@ -145,9 +166,8 @@ public EthernetPacket sendIcmpV6Echo(
145166 return icmpUnicastReply ;
146167 }
147168
148- public EthernetPacket sendNeighborSolicitation (int portIdx , int timeout , String dstIp )
149- throws ServiceModeRequiredException {
150- endTs = System .currentTimeMillis () + timeout * 1000 ;
169+ public EthernetPacket sendNeighborSolicitation (int portIdx , int timeout , String dstIp ) {
170+ long endTs = System .currentTimeMillis () + timeout * 1000 ;
151171 PortStatus portStatus = tRexClient .getPortStatus (portIdx ).get ();
152172
153173 srcMac = portStatus .getAttr ().getLayerConiguration ().getL2Configuration ().getSrc ();
@@ -180,6 +200,7 @@ public EthernetPacket sendNeighborSolicitation(int portIdx, int timeout, String
180200 && nodeIpv6 .equals (targetIpv6inNS )
181201 && dstIPv6Addr .equals (srcIPv6Addr );
182202 } catch (UnknownHostException ignored ) {
203+ // Do nothing
183204 }
184205 return false ;
185206 };
@@ -200,8 +221,8 @@ public EthernetPacket sendNeighborSolicitation(int portIdx, int timeout, String
200221 }
201222
202223 private Map <String , EthernetPacket > sendNSandIcmpV6Req (
203- int portIdx , int timeDuration , String dstIp ) throws ServiceModeRequiredException {
204- endTs = System .currentTimeMillis () + timeDuration * 1000 ;
224+ int portIdx , int timeDuration , String dstIp ) {
225+ long endTs = System .currentTimeMillis () + timeDuration * 1000 ;
205226 TRexClientResult <PortStatus > portStatusResult = tRexClient .getPortStatus (portIdx );
206227 PortStatus portStatus = portStatusResult .get ();
207228
@@ -236,6 +257,7 @@ private Map<String, EthernetPacket> sendNSandIcmpV6Req(
236257 (Inet6Address ) Inet6Address .getByName (generateIPv6AddrFromMAC (srcMac ));
237258 return !naIncomingRequests .containsKey (nodeIp ) && dstIPv6Addr .equals (srcIPv6Addr );
238259 } catch (UnknownHostException ignored ) {
260+ // Do nothing
239261 }
240262 return false ;
241263 };
@@ -256,9 +278,9 @@ private Map<String, EthernetPacket> sendNSandIcmpV6Req(
256278 }
257279
258280 private com .cisco .trex .stateless .model .Stream buildStream (Packet pkt ) {
259- int stream_id = (int ) (Math .random () * 1000 );
281+ int streamId = (int ) (Math .random () * 1000 );
260282 return new com .cisco .trex .stateless .model .Stream (
261- stream_id ,
283+ streamId ,
262284 true ,
263285 3 ,
264286 0.0 ,
@@ -271,7 +293,7 @@ private com.cisco.trex.stateless.model.Stream buildStream(Packet pkt) {
271293 StreamMode .Type .single_burst ),
272294 -1 ,
273295 pkt ,
274- new StreamRxStats (false , false , true , stream_id ),
296+ new StreamRxStats (false , false , true , streamId ),
275297 new StreamVM ("" , Collections .emptyList ()),
276298 true ,
277299 false ,
@@ -324,28 +346,19 @@ private Packet buildICMPV6NSPkt(String dstMac, String dstIp, String srcIp) {
324346 .payloadBuilder (ipV6Builder )
325347 .paddingAtBuild (true );
326348 } catch (UnknownHostException ignored ) {
349+ // Do nothing
327350 }
328351 return ethBuilder .build ();
329352 }
330353
331- private static EthernetPacket buildIdealICMPV6NSPkt (String pkt ) {
332- byte [] pktBin = Base64 .getDecoder ().decode (pkt );
333- try {
334- return EthernetPacket .newPacket (pktBin , 0 , pktBin .length );
335- } catch (IllegalRawDataException e ) {
336- e .printStackTrace ();
337- }
338- return null ;
339- }
340-
341354 /**
342355 * IPv6 Neighbor Discovery Source Link Layer Address header
343356 *
344357 * <p>0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
345358 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Length | Link-Layer
346359 * Address ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347360 */
348- private String getLinkLayerAddress (IpV6Packet pkt ) {
361+ private static String getLinkLayerAddress (IpV6Packet pkt ) {
349362 final int TYPE_OFFSET = 0 ;
350363 final int TYPE_SIZE = BYTE_SIZE_IN_BYTES ;
351364 final int LENGTH_OFFSET = TYPE_OFFSET + TYPE_SIZE ;
@@ -415,6 +428,7 @@ private Packet buildICMPV6NAPkt(String dstMac, String dstIp, String srcIP) {
415428 .payloadBuilder (ipV6Builder )
416429 .paddingAtBuild (true );
417430 } catch (UnknownHostException ignored ) {
431+ // Do nothing
418432 }
419433
420434 return ethBuilder .build ();
@@ -438,16 +452,12 @@ public static EthernetPacket buildICMPV6EchoReq(
438452 int icmpId ,
439453 int icmpSeq ) {
440454 /*
441-
442- mld_pkt = (Ether(src = self.src_mac, dst = self.dst_mld_mac) /
443- IPv6(src = self.src_ip, dst = self.dst_mld_ip, hlim = 1) /
444- IPv6ExtHdrHopByHop(options = [RouterAlert(), PadN()]) /
445- ICMPv6MLReportV2() /
446- MLDv2Addr(type = 4, len = 0, multicast_addr = 'ff02::2'))
447- ping_pkt = (Ether(src = self.src_mac, dst = dst_mac) /
448- IPv6(src = self.src_ip, dst = self.dst_ip, hlim = 1) /
449- ICMPv6EchoRequest())
450- return [self.vlan.embed(mld_pkt), self.vlan.embed(ping_pkt)]
455+ *
456+ * mld_pkt = (Ether(src = self.src_mac, dst = self.dst_mld_mac) / IPv6(src = self.src_ip, dst =
457+ * self.dst_mld_ip, hlim = 1) / IPv6ExtHdrHopByHop(options = [RouterAlert(), PadN()]) /
458+ * ICMPv6MLReportV2() / MLDv2Addr(type = 4, len = 0, multicast_addr = 'ff02::2')) ping_pkt =
459+ * (Ether(src = self.src_mac, dst = dst_mac) / IPv6(src = self.src_ip, dst = self.dst_ip, hlim =
460+ * 1) / ICMPv6EchoRequest()) return [self.vlan.embed(mld_pkt), self.vlan.embed(ping_pkt)]
451461 */
452462
453463 final String specifiedSrcIP = srcIp != null ? srcIp : generateIPv6AddrFromMAC (srcMacString );
@@ -478,7 +488,7 @@ public static EthernetPacket buildICMPV6EchoReq(
478488 .payloadBuilder (icmpCommonPktBuilder )
479489 .correctLengthAtBuild (true );
480490
481- MacAddress dstMac = null ;
491+ MacAddress dstMac ;
482492 if (dstMacString != null ) {
483493 dstMac = MacAddress .getByName (dstMacString );
484494 } else {
@@ -496,6 +506,7 @@ public static EthernetPacket buildICMPV6EchoReq(
496506
497507 return ethBuilder .build ();
498508 } catch (UnknownHostException ignore ) {
509+ // Do nothing
499510 }
500511 return null ;
501512 }
@@ -525,7 +536,7 @@ private static MacAddress multicastMacFromIPv6(String ipV6) {
525536 }
526537
527538 private static long [] divMod (long a , long b ) {
528- long result [] = new long [2 ];
539+ long [] result = new long [2 ];
529540
530541 result [1 ] = a % b ;
531542 result [0 ] = (a - result [1 ]) / b ;
0 commit comments