예제 #1
0
파일: ARP.java 프로젝트: jmdbo/CGR
  @Override
  public IPacket deserialize(byte[] data, int offset, int length) throws PacketParsingException {
    ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
    this.hardwareType = bb.getShort();
    this.protocolType = bb.getShort();
    this.hardwareAddressLength = bb.get();
    this.protocolAddressLength = bb.get();
    if (this.hardwareAddressLength != 6) {
      String msg = "Incorrect ARP hardware address length: " + hardwareAddressLength;
      throw new PacketParsingException(msg);
    }
    if (this.protocolAddressLength != 4) {
      String msg = "Incorrect ARP protocol address length: " + protocolAddressLength;
      throw new PacketParsingException(msg);
    }
    this.opCode = ArpOpcode.of(bb.getShort());

    byte[] tmpMac = new byte[0xff & this.hardwareAddressLength];
    byte[] tmpIp = new byte[0xff & this.protocolAddressLength];

    bb.get(tmpMac, 0, this.hardwareAddressLength);
    this.senderHardwareAddress = MacAddress.of(tmpMac);
    bb.get(tmpIp, 0, this.protocolAddressLength);
    this.senderProtocolAddress = IPv4Address.of(tmpIp);

    bb.get(tmpMac, 0, this.hardwareAddressLength);
    this.targetHardwareAddress = MacAddress.of(tmpMac);
    bb.get(tmpIp, 0, this.protocolAddressLength);
    this.targetProtocolAddress = IPv4Address.of(tmpIp);

    return this;
  }
  private OFAction buildL2Modification(Instruction i) {
    L2ModificationInstruction l2m = (L2ModificationInstruction) i;
    ModEtherInstruction eth;
    OFOxm<?> oxm = null;
    switch (l2m.subtype()) {
      case ETH_DST:
        eth = (ModEtherInstruction) l2m;
        oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
        break;
      case ETH_SRC:
        eth = (ModEtherInstruction) l2m;
        oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
        break;
      case VLAN_ID:
        ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
        oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
        break;
      case VLAN_PCP:
        ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
        oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
        break;
      case MPLS_PUSH:
        PushHeaderInstructions pushHeaderInstructions = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .pushMpls(EthType.of(pushHeaderInstructions.ethernetType().toShort()));
      case MPLS_POP:
        PushHeaderInstructions popHeaderInstructions = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .popMpls(EthType.of(popHeaderInstructions.ethernetType().toShort()));
      case MPLS_LABEL:
        ModMplsLabelInstruction mplsLabel = (ModMplsLabelInstruction) l2m;
        oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label().longValue()));
        break;
      case DEC_MPLS_TTL:
        return factory().actions().decMplsTtl();
      case VLAN_POP:
        return factory().actions().popVlan();
      case VLAN_PUSH:
        PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
        return factory()
            .actions()
            .pushVlan(EthType.of(pushVlanInstruction.ethernetType().toShort()));
      default:
        log.warn("Unimplemented action type {}.", l2m.subtype());
        break;
    }

    if (oxm != null) {
      return factory().actions().buildSetField().setField(oxm).build();
    }
    return null;
  }
  @Test
  public void emit() {

    MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
    MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");

    ARP arp = new ARP();
    arp.setSenderProtocolAddress(ANY)
        .setSenderHardwareAddress(mac1.getBytes())
        .setTargetHardwareAddress(mac2.getBytes())
        .setTargetProtocolAddress(ANY)
        .setHardwareType((short) 0)
        .setProtocolType((short) 0)
        .setHardwareAddressLength((byte) 6)
        .setProtocolAddressLength((byte) 4)
        .setOpCode((byte) 0);

    Ethernet eth = new Ethernet();
    eth.setVlanID(VLANID)
        .setEtherType(Ethernet.TYPE_ARP)
        .setSourceMACAddress("00:00:00:11:00:01")
        .setDestinationMACAddress("00:00:00:22:00:02")
        .setPayload(arp);

    // the should-be working setup.
    OutboundPacket passPkt = outPacket(DID, TR, eth);
    sw.setRole(RoleState.MASTER);
    provider.emit(passPkt);
    assertEquals("invalid switch", sw, controller.current);
    assertEquals("message not sent", PLIST.size(), sw.sent.size());
    sw.sent.clear();

    // wrong Role
    // sw.setRole(RoleState.SLAVE);
    // provider.emit(passPkt);
    // assertEquals("invalid switch", sw, controller.current);
    // assertEquals("message sent incorrectly", 0, sw.sent.size());

    // sw.setRole(RoleState.MASTER);

    // missing switch
    OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
    provider.emit(swFailPkt);
    assertNull("invalid switch", controller.current);
    assertEquals("message sent incorrectly", 0, sw.sent.size());

    // to missing port
    // OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
    // provider.emit(portFailPkt);
    // assertEquals("extra message sent", 1, sw.sent.size());

  }
예제 #4
0
  /**
   * Parse a mac adress from the canonical string representation as 6 hex bytes separated by colons
   * (01:02:03:04:05:06).
   *
   * @param macString - a mac address in canonical string representation
   * @return the parsed MacAddress
   * @throws IllegalArgumentException if macString is not a valid mac adddress
   */
  @Nonnull
  public static MacAddress of(@Nonnull final String macString) throws IllegalArgumentException {
    if (macString == null) {
      throw new NullPointerException("macString must not be null");
    }

    int index = 0;
    int shift = 40;
    long raw = 0;

    if (macString.length() != MAC_STRING_LENGTH) {
      throw new IllegalArgumentException(FORMAT_ERROR + macString);
    }

    while (shift >= 0) {
      int digit1 = Character.digit(macString.charAt(index++), 16);
      int digit2 = Character.digit(macString.charAt(index++), 16);
      if ((digit1 < 0) || (digit2 < 0))
        throw new IllegalArgumentException(FORMAT_ERROR + macString);
      raw |= ((long) (digit1 << 4 | digit2)) << shift;

      if (shift == 0) break;
      if (macString.charAt(index++) != ':')
        throw new IllegalArgumentException(FORMAT_ERROR + macString);
      shift -= 8;
    }
    return MacAddress.of(raw);
  }
예제 #5
0
 public static MacAddress of(final byte[] address) {
   if (address.length != MacAddrLen)
     throw new IllegalArgumentException(
         "Mac address byte array must be exactly 6 bytes long; length = " + address.length);
   long raw =
       (address[0] & 0xFFL) << 40
           | (address[1] & 0xFFL) << 32
           | (address[2] & 0xFFL) << 24
           | (address[3] & 0xFFL) << 16
           | (address[4] & 0xFFL) << 8
           | (address[5] & 0xFFL);
   return MacAddress.of(raw);
 }
예제 #6
0
  /*
   * Parse an IPv4 Multicast address and return the macAddress
   * corresponding to the multicast IPv4 address.
   *
   * For multicast forwarding, the mac addresses in the range
   * 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF have been reserved.
   * The most significant 25 bits of the above 48-bit mac address
   * are fixed while the lower 23 bits are variable.
   * These lower 23 bits are derived from the lower 23 bits
   * of the multicast IP address.
   *
   * AND ipv4 address with 0x07FFFFF to extract the last 23 bits
   * OR with 01:00:5E:00:00:00 MAC (first 25 bits)
   *
   * @param ipv4 - ipv4 multicast address
   * @return the MacAddress corresponding to the multicast address
   * @throws IllegalArgumentException if ipv4 is not a valid multicast address
   */
  @Nonnull
  public static MacAddress forIPv4MulticastAddress(IPv4Address ipv4)
      throws IllegalArgumentException {

    if (!ipv4.isMulticast())
      throw new IllegalArgumentException("Not a Multicast IPAddress\"" + ipv4 + "\"");

    long ipLong = ipv4.getInt();
    int ipMask = 0x007FFFFF;
    ipLong = ipLong & ipMask;

    long macLong = MULTICAST_BASE_ADDRESS.getLong(); // 01:00:5E:00:00:00
    macLong = macLong | ipLong;
    MacAddress returnMac = MacAddress.of(macLong);

    return returnMac;
  }
  @Test
  public void testWrite() {
    OFBsnGentableEntryDelete.Builder builder = factory.buildBsnGentableEntryDelete();
    builder
        .setXid(0x12345678)
        .setTableId(GenTableId.of(20))
        .setKey(
            ImmutableList.<OFBsnTlv>of(
                factory.bsnTlvs().port(OFPort.of(5)),
                factory.bsnTlvs().mac(MacAddress.of("01:23:45:67:89:ab"))));
    OFBsnGentableEntryDelete bsnGentableEntryDelete = builder.build();
    ByteBuf bb = Unpooled.buffer();
    bsnGentableEntryDelete.writeTo(bb);
    byte[] written = new byte[bb.readableBytes()];
    bb.readBytes(written);

    assertThat(written, CoreMatchers.equalTo(BSN_GENTABLE_ENTRY_DELETE_SERIALIZED));
  }
  @Test
  public void testRead() throws Exception {
    OFBsnGentableEntryDelete.Builder builder = factory.buildBsnGentableEntryDelete();
    builder
        .setXid(0x12345678)
        .setTableId(GenTableId.of(20))
        .setKey(
            ImmutableList.<OFBsnTlv>of(
                factory.bsnTlvs().port(OFPort.of(5)),
                factory.bsnTlvs().mac(MacAddress.of("01:23:45:67:89:ab"))));
    OFBsnGentableEntryDelete bsnGentableEntryDeleteBuilt = builder.build();

    ByteBuf input = Unpooled.copiedBuffer(BSN_GENTABLE_ENTRY_DELETE_SERIALIZED);

    // FIXME should invoke the overall reader once implemented
    OFBsnGentableEntryDelete bsnGentableEntryDeleteRead =
        OFBsnGentableEntryDeleteVer13.READER.readFrom(input);
    assertEquals(BSN_GENTABLE_ENTRY_DELETE_SERIALIZED.length, input.readerIndex());

    assertEquals(bsnGentableEntryDeleteBuilt, bsnGentableEntryDeleteRead);
  }
예제 #9
0
 @Override
 public MacAddress applyMask(MacAddress mask) {
   return MacAddress.of(this.rawValue & mask.rawValue);
 }
예제 #10
0
 public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
   long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
   return MacAddress.of(raw);
 }
예제 #11
0
/**
 * Wrapper around a 6 byte mac address.
 *
 * @author Andreas Wundsam {@literal <}[email protected]{@literal >}
 */
public class MacAddress implements OFValueType<MacAddress> {
  static final int MacAddrLen = 6;
  private final long rawValue;

  private static final long NONE_VAL = 0x0L;
  public static final MacAddress NONE = new MacAddress(NONE_VAL);

  private static final long BROADCAST_VAL = 0x0000FFFFFFFFFFFFL;
  public static final MacAddress BROADCAST = new MacAddress(BROADCAST_VAL);

  public static final MacAddress NO_MASK = MacAddress.of(0xFFFFFFFFFFFFFFFFl);
  public static final MacAddress FULL_MASK = MacAddress.of(0x0);

  private static final long LLDP_MAC_ADDRESS_MASK = 0xfffffffffff0L;
  private static final long LLDP_MAC_ADDRESS_VALUE = 0x0180c2000000L;
  private static final MacAddress MULTICAST_BASE_ADDRESS = MacAddress.of("01:00:5E:00:00:00");

  private static final String FORMAT_ERROR =
      "Mac address is not well-formed. "
          + "It must consist of 6 hex digit pairs separated by colons: ";
  private static final int MAC_STRING_LENGTH = 6 * 2 + 5;

  private MacAddress(final long rawValue) {
    this.rawValue = rawValue;
  }

  public static MacAddress of(final byte[] address) {
    if (address.length != MacAddrLen)
      throw new IllegalArgumentException(
          "Mac address byte array must be exactly 6 bytes long; length = " + address.length);
    long raw =
        (address[0] & 0xFFL) << 40
            | (address[1] & 0xFFL) << 32
            | (address[2] & 0xFFL) << 24
            | (address[3] & 0xFFL) << 16
            | (address[4] & 0xFFL) << 8
            | (address[5] & 0xFFL);
    return MacAddress.of(raw);
  }

  public static MacAddress of(long raw) {
    raw &= BROADCAST_VAL;
    if (raw == NONE_VAL) return NONE;
    if (raw == BROADCAST_VAL) return BROADCAST;
    return new MacAddress(raw);
  }

  /**
   * Parse a mac adress from the canonical string representation as 6 hex bytes separated by colons
   * (01:02:03:04:05:06).
   *
   * @param macString - a mac address in canonical string representation
   * @return the parsed MacAddress
   * @throws IllegalArgumentException if macString is not a valid mac adddress
   */
  @Nonnull
  public static MacAddress of(@Nonnull final String macString) throws IllegalArgumentException {
    if (macString == null) {
      throw new NullPointerException("macString must not be null");
    }

    int index = 0;
    int shift = 40;
    long raw = 0;

    if (macString.length() != MAC_STRING_LENGTH) {
      throw new IllegalArgumentException(FORMAT_ERROR + macString);
    }

    while (shift >= 0) {
      int digit1 = Character.digit(macString.charAt(index++), 16);
      int digit2 = Character.digit(macString.charAt(index++), 16);
      if ((digit1 < 0) || (digit2 < 0))
        throw new IllegalArgumentException(FORMAT_ERROR + macString);
      raw |= ((long) (digit1 << 4 | digit2)) << shift;

      if (shift == 0) break;
      if (macString.charAt(index++) != ':')
        throw new IllegalArgumentException(FORMAT_ERROR + macString);
      shift -= 8;
    }
    return MacAddress.of(raw);
  }

  /**
   * Creates a {@link MacAddress} from a {@link DatapathId}. This factory method assumes that the
   * first two bytes of the {@link DatapathId} are 0 bytes.
   *
   * @param dpid the {@link DatapathId} to create the {@link MacAddress} from
   * @return a {@link MacAddress} derived from the supplied {@link DatapathId}
   */
  public static MacAddress of(@Nonnull DatapathId dpid) {
    Preconditions.checkNotNull(dpid, "dpid must not be null");

    long raw = dpid.getLong();

    // Mask out valid bytes
    if ((raw & ~BROADCAST_VAL) != 0L) {
      throw new IllegalArgumentException("First two bytes of supplied " + "Datapathid must be 0");
    }
    return of(raw);
  }

  private volatile byte[] bytesCache = null;

  public byte[] getBytes() {
    if (bytesCache == null) {
      synchronized (this) {
        if (bytesCache == null) {
          bytesCache =
              new byte[] {
                (byte) ((rawValue >> 40) & 0xFF),
                (byte) ((rawValue >> 32) & 0xFF),
                (byte) ((rawValue >> 24) & 0xFF),
                (byte) ((rawValue >> 16) & 0xFF),
                (byte) ((rawValue >> 8) & 0xFF),
                (byte) ((rawValue >> 0) & 0xFF)
              };
        }
      }
    }
    return Arrays.copyOf(bytesCache, bytesCache.length);
  }

  /**
   * Returns {@code true} if the MAC address is the broadcast address.
   *
   * @return {@code true} if the MAC address is the broadcast address.
   */
  public boolean isBroadcast() {
    return this == BROADCAST;
  }

  /**
   * Returns {@code true} if the MAC address is a multicast address.
   *
   * @return {@code true} if the MAC address is a multicast address.
   */
  public boolean isMulticast() {
    if (isBroadcast()) {
      return false;
    }
    return (rawValue & (0x01L << 40)) != 0;
  }

  /**
   * Returns {@code true} if the MAC address is an LLDP mac address.
   *
   * @return {@code true} if the MAC address is an LLDP mac address.
   */
  public boolean isLLDPAddress() {
    return (rawValue & LLDP_MAC_ADDRESS_MASK) == LLDP_MAC_ADDRESS_VALUE;
  }

  @Override
  public int getLength() {
    return MacAddrLen;
  }

  @Override
  public String toString() {
    return HexString.toHexString(rawValue, 6);
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) (rawValue ^ (rawValue >>> 32));
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    MacAddress other = (MacAddress) obj;
    if (rawValue != other.rawValue) return false;
    return true;
  }

  public long getLong() {
    return rawValue;
  }

  public void write6Bytes(ChannelBuffer c) {
    c.writeInt((int) (this.rawValue >> 16));
    c.writeShort((int) this.rawValue & 0xFFFF);
  }

  public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
    long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
    return MacAddress.of(raw);
  }

  @Override
  public MacAddress applyMask(MacAddress mask) {
    return MacAddress.of(this.rawValue & mask.rawValue);
  }

  @Override
  public int compareTo(MacAddress o) {
    return Longs.compare(rawValue, o.rawValue);
  }

  @Override
  public void putTo(PrimitiveSink sink) {
    sink.putInt((int) (this.rawValue >> 16));
    sink.putShort((short) (this.rawValue & 0xFFFF));
  }

  /*
   * Parse an IPv4 Multicast address and return the macAddress
   * corresponding to the multicast IPv4 address.
   *
   * For multicast forwarding, the mac addresses in the range
   * 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF have been reserved.
   * The most significant 25 bits of the above 48-bit mac address
   * are fixed while the lower 23 bits are variable.
   * These lower 23 bits are derived from the lower 23 bits
   * of the multicast IP address.
   *
   * AND ipv4 address with 0x07FFFFF to extract the last 23 bits
   * OR with 01:00:5E:00:00:00 MAC (first 25 bits)
   *
   * @param ipv4 - ipv4 multicast address
   * @return the MacAddress corresponding to the multicast address
   * @throws IllegalArgumentException if ipv4 is not a valid multicast address
   */
  @Nonnull
  public static MacAddress forIPv4MulticastAddress(IPv4Address ipv4)
      throws IllegalArgumentException {

    if (!ipv4.isMulticast())
      throw new IllegalArgumentException("Not a Multicast IPAddress\"" + ipv4 + "\"");

    long ipLong = ipv4.getInt();
    int ipMask = 0x007FFFFF;
    ipLong = ipLong & ipMask;

    long macLong = MULTICAST_BASE_ADDRESS.getLong(); // 01:00:5E:00:00:00
    macLong = macLong | ipLong;
    MacAddress returnMac = MacAddress.of(macLong);

    return returnMac;
  }
}