Esempio n. 1
0
void MatchPacketBuilder::buildICMPv6_ND(ByteList *msg) const {
  assert(icmpType_ == ICMPV6_TYPE_NEIGHBOR_SOLICIT ||
         icmpType_ == ICMPV6_TYPE_NEIGHBOR_ADVERTISE);

  Big8 hdr[2];
  hdr[0] = (icmpType_ == ICMPV6_TYPE_NEIGHBOR_SOLICIT) ? ICMPV6_OPTION_SLL
                                                       : ICMPV6_OPTION_TLL;
  hdr[1] = 1;  // length in 8-octet units

  ByteList buf;
  Big32 ndRes = (icmpType_ == ICMPV6_TYPE_NEIGHBOR_ADVERTISE) ? ndRes_ : 0;
  buf.add(&ndRes, sizeof(ndRes));
  buf.add(&ndTarget_, sizeof(ndTarget_));
  buf.add(&hdr[0], sizeof(hdr));
  buf.add(&ndLl_, sizeof(ndLl_));

  buildICMPv6(msg, buf.toRange());
}
Esempio n. 2
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());
}