Flow.Builder fb = new Flow.Builder(); fb.setIpProtocol(IpProtocol.TCP); fb.setTag("neighbor-resolution"); fb.setIngressNode(initiator.getHostname()); fb.setIngressVrf(initiator.getVrfName()); fb.setSrcIp(srcAddress); fb.setDstIp(dstAddress); fb.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number()); fb.setDstPort(NamedPort.BGP.number()); Flow forwardFlow = fb.build(); fb.setIngressNode(acceptedHostname); fb.setIngressVrf(listener.getVrfName()); fb.setSrcIp(forwardFlow.getDstIp()); fb.setDstIp(forwardFlow.getSrcIp()); fb.setSrcPort(forwardFlow.getDstPort()); fb.setDstPort(forwardFlow.getSrcPort()); Flow backwardFlow = fb.build(); traces = tracerouteEngine.computeTraces(ImmutableSet.of(backwardFlow), false);
flow.setIngressNode(loc.getNode()); flow.setTag(flowTag); switch (loc.getType()) { case INTERFACE_LINK: flow.setIngressInterface(loc.getInterface()); break; case VRF: flow.setIngressVrf(loc.getVrf()); break; default: "Unexpected IngressLocation Type: " + loc.getType().name()); return Stream.of(flow.build()); }) .collect(ImmutableSet.toImmutableSet());
Flow flow = flowBuilder.get().setIngressNode("ingressNode").setTag("tag").build();
Optional<Ip> srcIp = _ipSpaceRepresentative.getRepresentative(space); checkArgument(srcIp.isPresent(), "Specified source: %s has no IPs", headerSrcIp); builder.setSrcIp(srcIp.get()); } else if (srcLocation == null) { builder.setSrcIp(DEFAULT_IP_ADDRESS); } else { "At least one source IP is required, location %s produced none", srcLocation); builder.setSrcIp(srcIp.get());
Flow.builder().setTag("tag").setIngressNode("node").setDstIp(Ip.parse("1.1.1.1")).build(); Environment environment = new Environment(null, null, null, null, null, null, null);
fb -> { IngressLocation loc = entry.getKey(); fb.setTag(flowTag); fb.setIngressNode(loc.getNode()); switch (loc.getType()) { case INTERFACE_LINK: fb.setIngressInterface(loc.getInterface()); break; case VRF: fb.setIngressVrf(loc.getVrf()); break; default: throw new BatfishException("Unknown Location Type: " + loc.getType()); return fb.build(); })) .flatMap(optional -> optional.map(Stream::of).orElse(Stream.empty()))
try { Flow.Builder flowBuilder = headerConstraintsToFlow(question.getHeaders(), null); flowBuilder.setIngressNode(node); flowBuilder.setIngressInterface(null); flowBuilder.setIngressVrf( flowBuilder.setTag("FlowTag"); // dummy tag; consistent tags enable flow diffs setBuilder.add(flowBuilder.build()); } catch (IllegalArgumentException e) { allProblems.add(e.getMessage()); Flow.Builder flowBuilder = headerConstraintsToFlow(question.getHeaders(), srcLocation); setSourceLocation(flowBuilder, srcLocation, c); flowBuilder.setTag("FlowTag"); // dummy tag; consistent tags enable flow diffs setBuilder.add(flowBuilder.build()); } catch (IllegalArgumentException e) {
@Test public void testDiffFlowTracesToRowsMaxTraces() { Flow flow = Flow.builder().setTag("tag").setIngressNode("node").setDstIp(Ip.parse("1.1.1.1")).build();
flow.setTag(flowTag); flow.setIngressNode(source.getNode()); switch (source.getType()) { case VRF: flow.setIngressVrf(source.getVrf()); break; case INTERFACE_LINK: flow.setIngressInterface(source.getInterface()); break; default: throw new BatfishException("Unexpected IngressLocationType: " + source.getType()); return Stream.of(flow.build()); }) .collect(ImmutableSet.toImmutableSet());
Integer tcpFlagsFin = isTrue(pkt.getTcpFin()) ? 0 : 1; Flow.Builder b = new Flow.Builder(); b.setIngressNode(routerName); b.setSrcIp(srcIp); b.setDstIp(dstIp); b.setSrcPort(srcPort); b.setDstPort(dstPort); b.setIpProtocol(ipProtocol); b.setIcmpType(icmpType); b.setIcmpCode(icmpCode); b.setTcpFlagsCwr(tcpFlagsCwr); b.setTcpFlagsEce(tcpFlagsEce); b.setTcpFlagsUrg(tcpFlagsUrg); b.setTcpFlagsAck(tcpFlagsAck); b.setTcpFlagsPsh(tcpFlagsPsh); b.setTcpFlagsRst(tcpFlagsRst); b.setTcpFlagsSyn(tcpFlagsSyn); b.setTcpFlagsFin(tcpFlagsFin); b.setTag("SMT"); return b.build();
/** Generate a set of flows to do traceroute */ @VisibleForTesting Set<Flow> getFlows(String tag) { Set<Location> srcLocations = LocationSpecifierFactory.load(SRC_LOCATION_SPECIFIER_FACTORY) .buildLocationSpecifier(_sourceLocationStr) .resolve(_specifierContext); ImmutableSet.Builder<Flow> setBuilder = ImmutableSet.builder(); ImmutableSet.Builder<String> allProblems = ImmutableSet.builder(); // Perform cross-product of all locations to flows for (Location srcLocation : srcLocations) { try { Flow.Builder flowBuilder = headerConstraintsToFlow(_packetHeaderConstraints, srcLocation); setSourceLocation(flowBuilder, srcLocation); flowBuilder.setTag(tag); setBuilder.add(flowBuilder.build()); } catch (IllegalArgumentException e) { // Try to ignore silently if possible allProblems.add(e.getMessage()); } } Set<Flow> flows = setBuilder.build(); checkArgument( !flows.isEmpty(), "Could not construct a flow for traceroute. Found issues: %s", String.join(",", allProblems.build())); return flows; }
@Test public void testDiffFlowTracesToRows() { Flow flow = Flow.builder().setTag("tag").setIngressNode("node").setDstIp(Ip.parse("1.1.1.1")).build();
private void setDstIp(PacketHeaderConstraints constraints, Builder builder) { String headerDstIp = constraints.getDstIps(); if (headerDstIp != null) { IpSpaceSpecifier dstIpSpecifier = IpSpaceSpecifierFactory.load(IP_SPECIFIER_FACTORY).buildIpSpaceSpecifier(headerDstIp); IpSpaceAssignment dstIps = dstIpSpecifier.resolve(ImmutableSet.of(), _batfish.specifierContext()); // Filter out empty IP assignments ImmutableList<Entry> nonEmptyIpSpaces = dstIps.getEntries().stream() .filter(e -> !e.getIpSpace().equals(EmptyIpSpace.INSTANCE)) .collect(ImmutableList.toImmutableList()); checkArgument( nonEmptyIpSpaces.size() > 0, "At least one destination IP is required, could not resolve any"); checkArgument( nonEmptyIpSpaces.size() == 1, "Specified destination: %s, resolves to more than one IP", headerDstIp); IpSpace space = nonEmptyIpSpaces.iterator().next().getIpSpace(); Optional<Ip> dstIp = _ipSpaceRepresentative.getRepresentative(space); checkArgument(dstIp.isPresent(), "Specified destination: %s has no IPs", headerDstIp); builder.setDstIp(dstIp.get()); } else { builder.setDstIp(DEFAULT_IP_ADDRESS); } }
@Test public void testMatchFlowIgnoreFields() { TcpFlags flags = TcpFlags.builder().setUrg(true).setRst(true).build(); // All fields ignored by default TcpFlagsMatchConditions conditions = TcpFlagsMatchConditions.builder().setTcpFlags(flags).build(); assertThat( conditions.match(Flow.builder().setTcpFlagsUrg(1).setIngressNode("n").setTag("t").build()), equalTo(true)); // Fields that do not match, but are ignored do not break match conditions = TcpFlagsMatchConditions.builder() .setTcpFlags(flags) .setUseUrg(false) .setUseRst(true) .build(); assertThat( conditions.match( Flow.builder() .setTcpFlagsUrg(0) .setTcpFlagsRst(1) .setIngressNode("n") .setTag("t") .build()), equalTo(true)); }
/** * Generate a flow builder given some set of packet header constraints. * * @param constraints {@link PacketHeaderConstraints} * @throws IllegalArgumentException if the {@code constraints} cannot be resolved to a single * value. */ private Flow.Builder headerConstraintsToFlow( PacketHeaderConstraints constraints, Location srcLocation) throws IllegalArgumentException { Flow.Builder builder = PacketHeaderConstraintsUtil.toFlow(constraints); // Extract and source IP from header constraints, setSrcIp(constraints, srcLocation, builder); setDstIp(constraints, builder); // Set defaults for protocol, and ports and packet lengths: if (builder.getIpProtocol() == null || builder.getIpProtocol() == IpProtocol.IP) { builder.setIpProtocol(IpProtocol.UDP); } if (builder.getDstPort() == 0) { builder.setDstPort(TRACEROUTE_PORT); } if (builder.getSrcPort() == 0) { builder.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number()); } return builder; }
/** * Generate a flow builder given some set of packet header constraints. * * @param constraints {@link PacketHeaderConstraints} * @throws IllegalArgumentException if the {@code constraints} cannot be resolved to a single * value. */ private Flow.Builder headerConstraintsToFlow( PacketHeaderConstraints constraints, Location srcLocation) throws IllegalArgumentException { Flow.Builder builder = PacketHeaderConstraintsUtil.toFlow(constraints); setSrcIp(constraints, srcLocation, builder); setDstIp(constraints, builder); // Set defaults for protocol, and ports and packet lengths: if (builder.getIpProtocol() == null || builder.getIpProtocol() == IpProtocol.IP) { builder.setIpProtocol(IpProtocol.TCP); } if (builder.getDstPort() == 0) { builder.setDstPort(NamedPort.HTTP.number()); } if (builder.getSrcPort() == 0) { builder.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number()); } return builder; }
protected static Flow createFlow( IngressLocation ingressLocation, Map<String, Long> constraints, String tag) { Flow.Builder flowBuilder = new Flow.Builder(); switch (ingressLocation.getType()) { case INTERFACE_LINK: flowBuilder .setIngressNode(ingressLocation.getNode()) .setIngressInterface(ingressLocation.getInterface()); break; case VRF: flowBuilder .setIngressNode(ingressLocation.getNode()) .setIngressVrf(ingressLocation.getVrf()); break; default: throw new BatfishException("Unexpected IngressLocation Type: " + ingressLocation.getType()); } flowBuilder.setTag(tag); constraints.forEach( (name, value) -> { if (!flowBuilders.containsKey(name)) { return; } flowBuilders.get(name).accept(flowBuilder, value); }); return flowBuilder.build(); }
public Flow.Builder getFlowFromAssignment(BDD satAssignment) { checkArgument(isAssignment(satAssignment)); Flow.Builder fb = Flow.builder(); fb.setDstIp(Ip.create(_dstIp.satAssignmentToLong(satAssignment))); fb.setSrcIp(Ip.create(_srcIp.satAssignmentToLong(satAssignment))); fb.setDstPort(_dstPort.satAssignmentToLong(satAssignment).intValue()); fb.setSrcPort(_srcPort.satAssignmentToLong(satAssignment).intValue()); fb.setIpProtocol( IpProtocol.fromNumber(_ipProtocol.satAssignmentToLong(satAssignment).intValue())); fb.setIcmpCode(_icmpCode.satAssignmentToLong(satAssignment).intValue()); fb.setIcmpType(_icmpType.satAssignmentToLong(satAssignment).intValue()); fb.setTcpFlagsAck(_tcpAck.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsCwr(_tcpCwr.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsEce(_tcpEce.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsFin(_tcpFin.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsPsh(_tcpPsh.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsRst(_tcpRst.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsSyn(_tcpSyn.and(satAssignment).isZero() ? 0 : 1); fb.setTcpFlagsUrg(_tcpUrg.and(satAssignment).isZero() ? 0 : 1); fb.setDscp(_dscp.satAssignmentToLong(satAssignment).intValue()); fb.setEcn(_ecn.satAssignmentToLong(satAssignment).intValue()); fb.setFragmentOffset(_fragmentOffset.satAssignmentToLong(satAssignment).intValue()); fb.setState(FlowState.fromNum(_state.satAssignmentToLong(satAssignment).intValue())); return fb; }
/** Compute the differences between two flows */ public static SortedSet<FlowDiff> flowDiffs(@Nullable Flow flow1, @Nullable Flow flow2) { if (flow1 == null || flow2 == null || flow1.equals(flow2)) { return ImmutableSortedSet.of(); } checkArgument( flow1 .toBuilder() .setDstIp(flow2.getDstIp()) .setSrcIp(flow2.getSrcIp()) .build() .equals(flow2), "flowDiff only supports differences of src or dst Ip"); ImmutableSortedSet.Builder<FlowDiff> diffs = ImmutableSortedSet.naturalOrder(); if (!flow1.getDstIp().equals(flow2.getDstIp())) { diffs.add( new FlowDiff(PROP_DST_IP, flow1.getDstIp().toString(), flow2.getDstIp().toString())); } if (!flow1.getSrcIp().equals(flow2.getSrcIp())) { diffs.add( new FlowDiff(PROP_SRC_IP, flow1.getSrcIp().toString(), flow2.getSrcIp().toString())); } return diffs.build(); }