Beispiel #1
0
RecordInfo findRecord(ByteRange searchRange,
                      ByteRange wholeRange,
                      uint32_t fileId) {
  static const uint32_t magic = Header::kMagic;
  static const ByteRange magicRange(reinterpret_cast<const uint8_t*>(&magic),
                                    sizeof(magic));

  DCHECK_GE(searchRange.begin(), wholeRange.begin());
  DCHECK_LE(searchRange.end(), wholeRange.end());

  const uint8_t* start = searchRange.begin();
  const uint8_t* end = std::min(searchRange.end(),
                                wholeRange.end() - sizeof(Header));
  // end-1: the last place where a Header could start
  while (start < end) {
    auto p = ByteRange(start, end + sizeof(magic)).find(magicRange);
    if (p == ByteRange::npos) {
      break;
    }

    start += p;
    auto r = validateRecord(ByteRange(start, wholeRange.end()), fileId);
    if (!r.record.empty()) {
      return r;
    }

    // No repeated prefix in magic, so we can do better than start++
    start += sizeof(magic);
  }

  return {0, {}};
}
Beispiel #2
0
void Normalize::normalizeQueueGetConfigReplyV1() {
  Header *hdr = header();

  size_t length = hdr->length();
  if (length < sizeof(QueueGetConfigReply)) {
    markInputInvalid("QueueGetConfigReply is too short");
    return;
  }

  if (hdr->version() == OFP_VERSION_1) {
    // Convert port number to 32-bits -- only for OpenFlow 1.0.
    UInt8 *ptr = buf_.mutableData() + sizeof(Header);
    PortNumber port = PortNumber::fromV1(*Big16_cast(ptr));
    std::memcpy(ptr, &port, sizeof(port));
  }

  // Convert QueueV1 to Queue.
  ByteRange data = SafeByteRange(buf_.mutableData(), buf_.size(),
                                 sizeof(QueueGetConfigReply));
  deprecated::QueueV1Range queues{data};

  Validation context;
  if (!queues.validateInput(&context)) {
    markInputInvalid("QueueGetConfigReply has invalid queues");
    return;
  }

  QueueList newQueues;
  for (auto &queue : queues) {
    QueueBuilder newQueue{queue};
    newQueues.add(newQueue);
  }

  // When converting to the regular `Queue` structure, we may exceed the max
  // message size of 65535.
  if (newQueues.size() > 65535 - sizeof(QueueGetConfigReply)) {
    markInputTooBig("QueueGetConfigReply is too big");
    return;
  }

  buf_.replace(data.begin(), data.end(), newQueues.data(), newQueues.size());
}
Beispiel #3
0
void Normalize::normalizeQueueGetConfigReplyV2() {
  // Pad all queues to a multiple of 8. You can only get a queue whose size is
  // not a multiple of 8 if it contains an experimenter property with an
  // unusual length.

  Header *hdr = header();

  size_t length = hdr->length();
  if (length < sizeof(QueueGetConfigReply))
    return;

  ByteRange data = SafeByteRange(buf_.mutableData(), buf_.size(),
                                 sizeof(QueueGetConfigReply));

  size_t remaining = data.size();
  const UInt8 *ptr = data.data();

  ByteList newBuf;
  while (remaining > 16) {
    // Read 16-bit queue length from a potentially mis-aligned position.
    UInt16 queueLen = Big16_unaligned(ptr + 8);
    if (queueLen > remaining || queueLen < 16)
      return;
    // Copy queue header.
    newBuf.add(ptr, 16);

    // Iterate over properties and pad out the properties whose sizes are not
    // multiples of 8.
    const UInt8 *prop = ptr + 16;
    size_t propLeft = queueLen - 16;
    while (propLeft > 4) {
      UInt16 propSize = Big16_unaligned(prop + 2);
      if (propSize > propLeft || propSize < 4)
        return;
      newBuf.add(prop, propSize);
      if ((propSize % 8) != 0) {
        newBuf.addZeros(PadLength(propSize) - propSize);
      }
      prop += propSize;
      propLeft -= propSize;
    }

    if (propLeft != 0) {
      log_debug("normalizeQueueGetConfigReplyV2: propLeft != 0");
      return;
    }

    ptr += queueLen;
    assert(prop == ptr);

    remaining -= queueLen;
  }

  if (remaining != 0) {
    log_debug("normalizeQueueGetConfigReplyV2: remaining != 0");
    return;
  }

  // When padding the regular `Queue` structure, we may exceed the max
  // message size of 65535.
  if (newBuf.size() > 65535 - sizeof(QueueGetConfigReply)) {
    markInputTooBig("QueueGetConfigReply is too big");
    return;
  }

  buf_.replace(data.begin(), data.end(), newBuf.data(), newBuf.size());
}
Beispiel #4
0
bool are_identical(const ByteRange& lhs, const ByteRange& rhs)
{
    return lhs.begin() == rhs.begin() && lhs.end() == rhs.end();
}