Example #1
0
File: ARP.java Project: 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;
  }
Example #2
0
File: ARP.java Project: jmdbo/CGR
 @Override
 public boolean equals(Object obj) {
   if (this == obj) return true;
   if (!super.equals(obj)) return false;
   if (getClass() != obj.getClass()) return false;
   ARP other = (ARP) obj;
   if (hardwareAddressLength != other.hardwareAddressLength) return false;
   if (hardwareType != other.hardwareType) return false;
   if (opCode == null) {
     if (other.opCode != null) return false;
   } else if (!opCode.equals(other.opCode)) return false;
   if (protocolAddressLength != other.protocolAddressLength) return false;
   if (protocolType != other.protocolType) return false;
   if (senderHardwareAddress == null) {
     if (other.senderHardwareAddress != null) return false;
   } else if (!senderHardwareAddress.equals(other.senderHardwareAddress)) return false;
   if (senderProtocolAddress == null) {
     if (other.senderProtocolAddress != null) return false;
   } else if (!senderProtocolAddress.equals(other.senderProtocolAddress)) return false;
   if (targetHardwareAddress == null) {
     if (other.targetHardwareAddress != null) return false;
   } else if (!targetHardwareAddress.equals(other.targetHardwareAddress)) return false;
   if (targetProtocolAddress == null) {
     if (other.targetProtocolAddress != null) return false;
   } else if (!targetProtocolAddress.equals(other.targetProtocolAddress)) return false;
   return true;
 }
  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;
  }
Example #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);
  }
    @Override
    public OFPortDesc readFrom(ByteBuf bb) throws OFParseError {
      OFPort portNo = OFPort.read4Bytes(bb);
      // pad: 4 bytes
      bb.skipBytes(4);
      MacAddress hwAddr = MacAddress.read6Bytes(bb);
      // pad: 2 bytes
      bb.skipBytes(2);
      String name = ChannelUtils.readFixedLengthString(bb, 16);
      Set<OFPortConfig> config = OFPortConfigSerializerVer12.readFrom(bb);
      Set<OFPortState> state = OFPortStateSerializerVer12.readFrom(bb);
      Set<OFPortFeatures> curr = OFPortFeaturesSerializerVer12.readFrom(bb);
      Set<OFPortFeatures> advertised = OFPortFeaturesSerializerVer12.readFrom(bb);
      Set<OFPortFeatures> supported = OFPortFeaturesSerializerVer12.readFrom(bb);
      Set<OFPortFeatures> peer = OFPortFeaturesSerializerVer12.readFrom(bb);
      long currSpeed = U32.f(bb.readInt());
      long maxSpeed = U32.f(bb.readInt());

      OFPortDescVer12 portDescVer12 =
          new OFPortDescVer12(
              portNo,
              hwAddr,
              name,
              config,
              state,
              curr,
              advertised,
              supported,
              peer,
              currSpeed,
              maxSpeed);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", portDescVer12);
      return portDescVer12;
    }
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;

    result = prime * result + ((value == null) ? 0 : value.hashCode());
    return result;
  }
Example #7
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;
  }
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;

    result = prime * result + ((dlAddr == null) ? 0 : dlAddr.hashCode());
    return result;
  }
Example #9
0
File: ARP.java Project: jmdbo/CGR
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = super.hashCode();
   result = prime * result + hardwareAddressLength;
   result = prime * result + hardwareType;
   result = prime * result + ((opCode == null) ? 0 : opCode.hashCode());
   result = prime * result + protocolAddressLength;
   result = prime * result + protocolType;
   result =
       prime * result + ((senderHardwareAddress == null) ? 0 : senderHardwareAddress.hashCode());
   result =
       prime * result + ((senderProtocolAddress == null) ? 0 : senderProtocolAddress.hashCode());
   result =
       prime * result + ((targetHardwareAddress == null) ? 0 : targetHardwareAddress.hashCode());
   result =
       prime * result + ((targetProtocolAddress == null) ? 0 : targetProtocolAddress.hashCode());
   return result;
 }
    @Override
    public OFOxmArpTha readFrom(ChannelBuffer bb) throws OFParseError {
      // fixed value property typeLen == 0x80003206L
      int typeLen = bb.readInt();
      if (typeLen != (int) 0x80003206)
        throw new OFParseError("Wrong typeLen: Expected=0x80003206L(0x80003206L), got=" + typeLen);
      MacAddress value = MacAddress.read6Bytes(bb);

      OFOxmArpThaVer13 oxmArpThaVer13 = new OFOxmArpThaVer13(value);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", oxmArpThaVer13);
      return oxmArpThaVer13;
    }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    OFActionSetDlSrcVer10 other = (OFActionSetDlSrcVer10) obj;

    if (dlAddr == null) {
      if (other.dlAddr != null) return false;
    } else if (!dlAddr.equals(other.dlAddr)) return false;
    return true;
  }
    @Override
    public OFOxmEthSrc readFrom(ByteBuf bb) throws OFParseError {
      // fixed value property typeLen == 0x80000806L
      int typeLen = bb.readInt();
      if (typeLen != (int) 0x80000806)
        throw new OFParseError("Wrong typeLen: Expected=0x80000806L(0x80000806L), got=" + typeLen);
      MacAddress value = MacAddress.read6Bytes(bb);

      OFOxmEthSrcVer12 oxmEthSrcVer12 = new OFOxmEthSrcVer12(value);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", oxmEthSrcVer12);
      return oxmEthSrcVer12;
    }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    OFOxmBsnInnerEthDstVer14 other = (OFOxmBsnInnerEthDstVer14) obj;

    if (value == null) {
      if (other.value != null) return false;
    } else if (!value.equals(other.value)) return false;
    return true;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    OFBsnTlvActorSystemMacVer14 other = (OFBsnTlvActorSystemMacVer14) obj;

    if (value == null) {
      if (other.value != null) return false;
    } else if (!value.equals(other.value)) return false;
    return true;
  }
    @Override
    public OFOxmBsnInnerEthDst readFrom(ByteBuf bb) throws OFParseError {
      // fixed value property typeLen == 0x32c06L
      int typeLen = bb.readInt();
      if (typeLen != 0x32c06)
        throw new OFParseError("Wrong typeLen: Expected=0x32c06L(0x32c06L), got=" + typeLen);
      MacAddress value = MacAddress.read6Bytes(bb);

      OFOxmBsnInnerEthDstVer14 oxmBsnInnerEthDstVer14 = new OFOxmBsnInnerEthDstVer14(value);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", oxmBsnInnerEthDstVer14);
      return oxmBsnInnerEthDstVer14;
    }
Example #16
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);
 }
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;

    result = prime * result + ((portNo == null) ? 0 : portNo.hashCode());
    result = prime * result + ((hwAddr == null) ? 0 : hwAddr.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((config == null) ? 0 : config.hashCode());
    result = prime * result + ((state == null) ? 0 : state.hashCode());
    result = prime * result + ((curr == null) ? 0 : curr.hashCode());
    result = prime * result + ((advertised == null) ? 0 : advertised.hashCode());
    result = prime * result + ((supported == null) ? 0 : supported.hashCode());
    result = prime * result + ((peer == null) ? 0 : peer.hashCode());
    result = prime * (int) (currSpeed ^ (currSpeed >>> 32));
    result = prime * (int) (maxSpeed ^ (maxSpeed >>> 32));
    return result;
  }
  @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 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());

  }
Example #20
0
  /**
   * Returns a specific available IP address binding for lease. The MAC and IP will be queried
   * against the DHCP pool. (1) If the MAC is found in an available, fixed binding, and that binding
   * is not for the provided IP, the fixed binding associated with the MAC will be returned. (2) If
   * the IP is found in an available, fixed binding, and that binding also contains the MAC address
   * provided, then the binding will be returned -- this is true only if the IP and MAC result in
   * the same available, fixed binding. (3) If the IP is found in the pool and it is available and
   * not fixed, then its binding will be returned. (4) If the IP provided does not match any
   * available entries or is invalid, null will be returned. If this is the case, run
   * getAnyAvailableLease(mac) to resolve.
   *
   * @param {@code byte[]}: The IP address on which to try and obtain a lease
   * @param {@code byte[]}: The MAC address on which to try and obtain a lease.
   * @return {@code DHCPBinding}: Reference to the DHCPBinding object if successful, null if
   *     unsuccessful.
   */
  public DHCPBinding getSpecificAvailableLease(IPv4Address ip, MacAddress mac) {
    if (ip == null || mac == null || isPoolFull()) return null;

    DHCPBinding binding = this.getDHCPbindingFromIPv4(ip);
    DHCPBinding binding2 = this.getDHCPbindingFromMAC(mac);

    // For all of the following, the binding is also determined to be inactive:

    // If configured, we must return a fixed binding for a MAC address even if it's requesting
    // another IP
    if (binding2 != null
        && !binding2.isActiveLease()
        && binding2.isStaticIPLease()
        && binding != binding2) {
      if (log != null)
        log.info("Fixed DHCP entry for MAC trumps requested IP. Returning binding for MAC");
      return binding2;
      // If configured, we must return a fixed binding for an IP if the binding is fixed to the
      // provided MAC (ideal static request case)
    } else if (binding != null
        && !binding.isActiveLease()
        && binding.isStaticIPLease()
        && mac.equals(binding.getMACAddress())) {
      if (log != null)
        log.info(
            "Found matching fixed DHCP entry for IP with MAC. Returning binding for IP with MAC");
      return binding;
      // The IP and MAC are not a part of a fixed binding, so return the binding of the requested IP
    } else if (binding != null && !binding.isActiveLease() && !binding.isStaticIPLease()) {
      if (log != null)
        log.info("No fixed DHCP entry for IP or MAC found. Returning dynamic binding for IP.");
      return binding;
      // Otherwise, the binding is fixed for both MAC and IP and this MAC does not match either, so
      // we can't return it as available
    } else {
      if (log != null)
        log.debug(
            "Invalid IP address request or IP is actively leased...check for any available lease to resolve");
      return null;
    }
  }
  @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);
  }
    @Override
    public OFBsnTlvActorSystemMac readFrom(ChannelBuffer bb) throws OFParseError {
      int start = bb.readerIndex();
      // fixed value property type == 0x29
      short type = bb.readShort();
      if (type != (short) 0x29)
        throw new OFParseError("Wrong type: Expected=0x29(0x29), got=" + type);
      int length = U16.f(bb.readShort());
      if (length != 10) throw new OFParseError("Wrong length: Expected=10(10), got=" + length);
      if (bb.readableBytes() + (bb.readerIndex() - start) < length) {
        // Buffer does not have all data yet
        bb.readerIndex(start);
        return null;
      }
      if (logger.isTraceEnabled()) logger.trace("readFrom - length={}", length);
      MacAddress value = MacAddress.read6Bytes(bb);

      OFBsnTlvActorSystemMacVer14 bsnTlvActorSystemMacVer14 =
          new OFBsnTlvActorSystemMacVer14(value);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", bsnTlvActorSystemMacVer14);
      return bsnTlvActorSystemMacVer14;
    }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    OFPortDescVer12 other = (OFPortDescVer12) obj;

    if (portNo == null) {
      if (other.portNo != null) return false;
    } else if (!portNo.equals(other.portNo)) return false;
    if (hwAddr == null) {
      if (other.hwAddr != null) return false;
    } else if (!hwAddr.equals(other.hwAddr)) return false;
    if (name == null) {
      if (other.name != null) return false;
    } else if (!name.equals(other.name)) return false;
    if (config == null) {
      if (other.config != null) return false;
    } else if (!config.equals(other.config)) return false;
    if (state == null) {
      if (other.state != null) return false;
    } else if (!state.equals(other.state)) return false;
    if (curr == null) {
      if (other.curr != null) return false;
    } else if (!curr.equals(other.curr)) return false;
    if (advertised == null) {
      if (other.advertised != null) return false;
    } else if (!advertised.equals(other.advertised)) return false;
    if (supported == null) {
      if (other.supported != null) return false;
    } else if (!supported.equals(other.supported)) return false;
    if (peer == null) {
      if (other.peer != null) return false;
    } else if (!peer.equals(other.peer)) return false;
    if (currSpeed != other.currSpeed) return false;
    if (maxSpeed != other.maxSpeed) return false;
    return true;
  }
    @Override
    public OFActionSetDlSrc readFrom(ByteBuf bb) throws OFParseError {
      int start = bb.readerIndex();
      // fixed value property type == 4
      short type = bb.readShort();
      if (type != (short) 0x4)
        throw new OFParseError("Wrong type: Expected=OFActionType.SET_DL_SRC(4), got=" + type);
      int length = U16.f(bb.readShort());
      if (length != 16) throw new OFParseError("Wrong length: Expected=16(16), got=" + length);
      if (bb.readableBytes() + (bb.readerIndex() - start) < length) {
        // Buffer does not have all data yet
        bb.readerIndex(start);
        return null;
      }
      if (logger.isTraceEnabled()) logger.trace("readFrom - length={}", length);
      MacAddress dlAddr = MacAddress.read6Bytes(bb);
      // pad: 6 bytes
      bb.skipBytes(6);

      OFActionSetDlSrcVer10 actionSetDlSrcVer10 = new OFActionSetDlSrcVer10(dlAddr);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", actionSetDlSrcVer10);
      return actionSetDlSrcVer10;
    }
Example #25
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;
  }
}
Example #26
0
 public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
   long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
   return MacAddress.of(raw);
 }
Example #27
0
 @Override
 public MacAddress applyMask(MacAddress mask) {
   return MacAddress.of(this.rawValue & mask.rawValue);
 }