Skip to content

Commit 1ecd6fe

Browse files
Merge pull request #94 from cisco-system-traffic-generator/ipv6ns
exception handling IPv6NeighborDiscoveryService change to correct multicast address as dst ip
2 parents 2f68a33 + b787909 commit 1ecd6fe

File tree

1 file changed

+63
-41
lines changed

1 file changed

+63
-41
lines changed

src/main/java/com/cisco/trex/stateless/IPv6NeighborDiscoveryService.java

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.google.common.collect.Lists;
1515
import com.google.common.net.InetAddresses;
1616
import java.net.Inet6Address;
17+
import java.net.InetAddress;
1718
import java.net.UnknownHostException;
1819
import java.util.AbstractMap;
1920
import java.util.ArrayList;
@@ -173,7 +174,7 @@ public EthernetPacket sendIcmpV6Echo(
173174
while (endTimeSec > System.currentTimeMillis()) {
174175
List<EthernetPacket> rxQueue =
175176
tRexClient.getRxQueue(portIdx, pkt -> pkt.contains(IcmpV6EchoReplyPacket.class));
176-
if (rxQueue.size() > 0) {
177+
if (!rxQueue.isEmpty()) {
177178
icmpUnicastReply = rxQueue.get(0);
178179
}
179180
}
@@ -221,19 +222,18 @@ public EthernetPacket sendNeighborSolicitation(
221222
String dstAddr = ipV6Header.getDstAddr().toString().substring(1);
222223

223224
try {
224-
Inet6Address dstIPv6Addr = (Inet6Address) Inet6Address.getByName(dstAddr);
225+
Inet6Address dstIPv6Addr = (Inet6Address) InetAddress.getByName(dstAddr);
225226
Inet6Address srcIPv6Addr =
226-
(Inet6Address) Inet6Address.getByName(generateIPv6AddrFromMAC(srcMac));
227+
(Inet6Address) InetAddress.getByName(generateIPv6AddrFromMAC(srcMac));
227228

228-
Inet6Address nodeIpv6 = (Inet6Address) Inet6Address.getByName(nodeIp);
229-
Inet6Address targetIpv6inNS = (Inet6Address) Inet6Address.getByName(dstIp);
229+
Inet6Address nodeIpv6 = (Inet6Address) InetAddress.getByName(nodeIp);
230+
Inet6Address targetIpv6inNS = (Inet6Address) InetAddress.getByName(dstIp);
230231
return icmpV6NaHdr.getSolicitedFlag()
231232
&& nodeIpv6.equals(targetIpv6inNS)
232233
&& dstIPv6Addr.equals(srcIPv6Addr);
233-
} catch (UnknownHostException ignored) {
234-
// Do nothing
234+
} catch (UnknownHostException e) {
235+
throw new IllegalArgumentException("Invalid address", e);
235236
}
236-
return false;
237237
};
238238

239239
EthernetPacket na = null;
@@ -312,14 +312,13 @@ private Map<String, EthernetPacket> sendNSandIcmpV6Req(
312312
String dstAddr = ipV6Header.getDstAddr().toString().substring(1);
313313

314314
try {
315-
Inet6Address dstIPv6Addr = (Inet6Address) Inet6Address.getByName(dstAddr);
315+
Inet6Address dstIPv6Addr = (Inet6Address) InetAddress.getByName(dstAddr);
316316
Inet6Address srcIPv6Addr =
317-
(Inet6Address) Inet6Address.getByName(generateIPv6AddrFromMAC(srcMac));
317+
(Inet6Address) InetAddress.getByName(generateIPv6AddrFromMAC(srcMac));
318318
return !naIncomingRequests.containsKey(nodeIp) && dstIPv6Addr.equals(srcIPv6Addr);
319-
} catch (UnknownHostException ignored) {
320-
// Do nothing
319+
} catch (UnknownHostException e) {
320+
throw new IllegalArgumentException("Invalid address", e);
321321
}
322-
return false;
323322
};
324323

325324
while (endTs > System.currentTimeMillis()) {
@@ -337,7 +336,7 @@ private Map<String, EthernetPacket> sendNSandIcmpV6Req(
337336
return naIncomingRequests;
338337
}
339338

340-
private com.cisco.trex.stateless.model.Stream buildStream(Packet pkt) {
339+
private static com.cisco.trex.stateless.model.Stream buildStream(Packet pkt) {
341340
int streamId = (int) (Math.random() * 1000);
342341
return new com.cisco.trex.stateless.model.Stream(
343342
streamId,
@@ -360,7 +359,7 @@ private com.cisco.trex.stateless.model.Stream buildStream(Packet pkt) {
360359
null);
361360
}
362361

363-
private Packet buildICMPV6NSPkt(
362+
private static Packet buildICMPV6NSPkt(
364363
PortVlan vlan, String srcMac, String dstMac, String dstIp, String srcIp) {
365364
EthernetPacket.Builder ethBuilder = new EthernetPacket.Builder();
366365
try {
@@ -375,23 +374,29 @@ private Packet buildICMPV6NSPkt(
375374
new IcmpV6NeighborSolicitationPacket.Builder();
376375
ipv6NSBuilder
377376
.options(Arrays.asList(sourceLLAddr))
378-
.targetAddress((Inet6Address) Inet6Address.getByName(dstIp));
377+
.targetAddress((Inet6Address) InetAddress.getByName(dstIp));
379378

380379
final String specifiedSrcIP = srcIp != null ? srcIp : generateIPv6AddrFromMAC(srcMac);
381380

382381
IcmpV6CommonPacket.Builder icmpCommonPktBuilder = new IcmpV6CommonPacket.Builder();
383382
icmpCommonPktBuilder
384-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
385-
.dstAddr((Inet6Address) Inet6Address.getByName(dstIp))
383+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
384+
.dstAddr((Inet6Address) InetAddress.getByName(dstIp))
386385
.type(IcmpV6Type.NEIGHBOR_SOLICITATION)
387386
.code(IcmpV6Code.NO_CODE)
388387
.correctChecksumAtBuild(true)
389388
.payloadBuilder(ipv6NSBuilder);
390389

390+
// Calculate the Solicited-Node multicast address, RFC 4291 chapter 2.7.1
391+
String[] destIpParts = dstIp.split(":");
392+
String multicastIp =
393+
String.format(
394+
"FF02::1:FF%s:%s", destIpParts[6].substring(2, 4), destIpParts[7].substring(0, 4));
395+
391396
IpV6Packet.Builder ipV6Builder = new IpV6Packet.Builder();
392397
ipV6Builder
393-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
394-
.dstAddr((Inet6Address) Inet6Address.getByName(dstIp))
398+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
399+
.dstAddr((Inet6Address) InetAddress.getByName(multicastIp))
395400
.version(IpVersion.IPV6)
396401
.hopLimit((byte) -1)
397402
.trafficClass(IpV6SimpleTrafficClass.newInstance((byte) 0))
@@ -413,8 +418,8 @@ private Packet buildICMPV6NSPkt(
413418
.payloadBuilder(payload.getValue())
414419
.paddingAtBuild(true);
415420

416-
} catch (UnknownHostException ignored) {
417-
// Do nothing
421+
} catch (UnknownHostException e) {
422+
throw new IllegalArgumentException("Invalid address", e);
418423
}
419424
return ethBuilder.build();
420425
}
@@ -447,7 +452,7 @@ private static String getLinkLayerAddress(IpV6Packet pkt) {
447452
return ByteArrays.toHexString(linkLayerAddress, ":");
448453
}
449454

450-
private Packet buildICMPV6NAPkt(
455+
private static Packet buildICMPV6NAPkt(
451456
PortVlan vlan, String srcMac, String dstMac, String dstIp, String srcIP) {
452457
final String specifiedSrcIP = srcIP != null ? srcIP : generateIPv6AddrFromMAC(srcMac);
453458

@@ -467,21 +472,21 @@ private Packet buildICMPV6NAPkt(
467472
.options(Arrays.asList(tLLAddr))
468473
.solicitedFlag(true)
469474
.overrideFlag(true)
470-
.targetAddress((Inet6Address) Inet6Address.getByName(specifiedSrcIP));
475+
.targetAddress((Inet6Address) InetAddress.getByName(specifiedSrcIP));
471476

472477
IcmpV6CommonPacket.Builder icmpCommonPktBuilder = new IcmpV6CommonPacket.Builder();
473478
icmpCommonPktBuilder
474-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
475-
.dstAddr((Inet6Address) Inet6Address.getByName(dstIp))
479+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
480+
.dstAddr((Inet6Address) InetAddress.getByName(dstIp))
476481
.type(IcmpV6Type.NEIGHBOR_ADVERTISEMENT)
477482
.code(IcmpV6Code.NO_CODE)
478483
.correctChecksumAtBuild(true)
479484
.payloadBuilder(ipv6NABuilder);
480485

481486
IpV6Packet.Builder ipV6Builder = new IpV6Packet.Builder();
482487
ipV6Builder
483-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
484-
.dstAddr((Inet6Address) Inet6Address.getByName(dstIp))
488+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
489+
.dstAddr((Inet6Address) InetAddress.getByName(dstIp))
485490
.version(IpVersion.IPV6)
486491
.trafficClass(IpV6SimpleTrafficClass.newInstance((byte) 0))
487492
.flowLabel(IpV6SimpleFlowLabel.newInstance(0))
@@ -503,8 +508,8 @@ private Packet buildICMPV6NAPkt(
503508
.payloadBuilder(payload.getValue())
504509
.paddingAtBuild(true);
505510

506-
} catch (UnknownHostException ignored) {
507-
// Do nothing
511+
} catch (UnknownHostException e) {
512+
throw new IllegalArgumentException("Invalid address", e);
508513
}
509514

510515
return ethBuilder.build();
@@ -527,6 +532,19 @@ public static EthernetPacket buildICMPV6EchoReq(
527532
String dstIp,
528533
int icmpId,
529534
int icmpSeq) {
535+
PortVlan vlan = new PortVlan();
536+
vlan.setTags(new ArrayList<Integer>());
537+
return buildICMPV6EchoReq(vlan, srcIp, srcMacString, dstMacString, dstIp, icmpId, icmpSeq);
538+
}
539+
540+
public static EthernetPacket buildICMPV6EchoReq(
541+
PortVlan vlan,
542+
String srcIp,
543+
String srcMacString,
544+
String dstMacString,
545+
String dstIp,
546+
int icmpId,
547+
int icmpSeq) {
530548
/*
531549
*
532550
* mld_pkt = (Ether(src = self.src_mac, dst = self.dst_mld_mac) / IPv6(src = self.src_ip, dst =
@@ -544,18 +562,18 @@ public static EthernetPacket buildICMPV6EchoReq(
544562
IcmpV6CommonPacket.Builder icmpCommonPktBuilder = new IcmpV6CommonPacket.Builder();
545563
try {
546564
icmpCommonPktBuilder
547-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
565+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
548566
.dstAddr(
549-
(Inet6Address) Inet6Address.getByName(dstIp != null ? dstIp : "ff02:0:0:0:0:0:0:1"))
567+
(Inet6Address) InetAddress.getByName(dstIp != null ? dstIp : "ff02:0:0:0:0:0:0:1"))
550568
.type(IcmpV6Type.ECHO_REQUEST)
551569
.code(IcmpV6Code.NO_CODE)
552570
.correctChecksumAtBuild(true)
553571
.payloadBuilder(icmpV6ERBuilder);
554572
IpV6Packet.Builder ipV6Builder = new IpV6Packet.Builder();
555573
ipV6Builder
556-
.srcAddr((Inet6Address) Inet6Address.getByName(specifiedSrcIP))
574+
.srcAddr((Inet6Address) InetAddress.getByName(specifiedSrcIP))
557575
.dstAddr(
558-
(Inet6Address) Inet6Address.getByName(dstIp != null ? dstIp : "ff02:0:0:0:0:0:0:1"))
576+
(Inet6Address) InetAddress.getByName(dstIp != null ? dstIp : "ff02:0:0:0:0:0:0:1"))
559577
.version(IpVersion.IPV6)
560578
.trafficClass(IpV6SimpleTrafficClass.newInstance((byte) 0))
561579
.flowLabel(IpV6SimpleFlowLabel.newInstance(0))
@@ -573,18 +591,24 @@ public static EthernetPacket buildICMPV6EchoReq(
573591
}
574592

575593
EthernetPacket.Builder ethBuilder = new EthernetPacket.Builder();
594+
AbstractMap.SimpleEntry<EtherType, Packet.Builder> payload =
595+
new AbstractMap.SimpleEntry<>(EtherType.IPV6, ipV6Builder);
596+
if (!vlan.getTags().isEmpty()) {
597+
payload = buildVlan(ipV6Builder, vlan);
598+
}
599+
576600
ethBuilder
577-
.type(EtherType.IPV6)
578601
.srcAddr(MacAddress.getByName(srcMacString))
579602
.dstAddr(dstMac)
580-
.payloadBuilder(ipV6Builder)
603+
.dstAddr(dstMac)
604+
.type(payload.getKey())
605+
.payloadBuilder(payload.getValue())
581606
.paddingAtBuild(true);
582607

583608
return ethBuilder.build();
584-
} catch (UnknownHostException ignore) {
585-
// Do nothing
609+
} catch (UnknownHostException e) {
610+
throw new IllegalArgumentException("Invalid address", e);
586611
}
587-
return null;
588612
}
589613

590614
public static EthernetPacket buildICMPV6EchoReq(
@@ -613,10 +637,8 @@ private static MacAddress multicastMacFromIPv6(String ipV6) {
613637

614638
private static long[] divMod(long a, long b) {
615639
long[] result = new long[2];
616-
617640
result[1] = a % b;
618641
result[0] = (a - result[1]) / b;
619-
620642
return result;
621643
}
622644

0 commit comments

Comments
 (0)