Exemplo n.º 1
0
/* static */ void IPv6RouteAdvertiser::createAdvertisementPacket(
    const Interface* intf,
    folly::io::RWPrivateCursor* cursor,
    folly::MacAddress dstMac,
    const folly::IPAddressV6& dstIP) {
  const auto* ndpConfig = &intf->getNdpConfig();

  // Settings
  uint8_t hopLimit = ndpConfig->curHopLimit;
  // Set managed and other bits in router advertisements.
  // These bits control whether address and other information
  // (e.g. where to grab the image) is available via DHCP.
  uint8_t flags = 0;
  if (ndpConfig->routerAdvertisementManagedBit) {
    flags |= ND_RA_FLAG_MANAGED;
  }
  if (ndpConfig->routerAdvertisementOtherBit) {
    flags |= ND_RA_FLAG_OTHER;
  }
  std::chrono::seconds lifetime(ndpConfig->routerLifetime);
  std::chrono::seconds reachableTimer(0);
  std::chrono::seconds retransTimer(0);
  uint32_t prefixValidLifetime = ndpConfig->prefixValidLifetimeSeconds;
  uint32_t prefixPreferredLifetime = ndpConfig->prefixPreferredLifetimeSeconds;

  // Build the list of prefixes to advertise
  typedef std::pair<IPAddressV6, uint8_t> Prefix;
  uint32_t mtu = intf->getMtu();
  std::set<Prefix> prefixes;
  foreachAddrToAdvertise(intf, [&](
    const std::pair<folly::IPAddress, uint8_t> & addr) {
      uint8_t mask = addr.second;
      prefixes.emplace(addr.first.asV6().mask(mask), mask);
    });

  auto serializeBody = [&](RWPrivateCursor* cursor) {
    cursor->writeBE<uint8_t>(hopLimit);
    cursor->writeBE<uint8_t>(flags);
    cursor->writeBE<uint16_t>(lifetime.count());
    cursor->writeBE<uint32_t>(reachableTimer.count());
    cursor->writeBE<uint32_t>(retransTimer.count());

    // Source MAC option
    cursor->writeBE<uint8_t>(1); // Option type (src link-layer address)
    cursor->writeBE<uint8_t>(1); // Option length = 1 (x8)
    cursor->push(intf->getMac().bytes(), MacAddress::SIZE);

    // Prefix options
    for (const auto& prefix : prefixes) {
      cursor->writeBE<uint8_t>(3); // Option type (prefix information)
      cursor->writeBE<uint8_t>(4); // Option length = 4 (x8)
      cursor->writeBE<uint8_t>(prefix.second);
      uint8_t prefixFlags = 0xc0; // on link, autonomous address configuration
      cursor->writeBE<uint8_t>(prefixFlags);
      cursor->writeBE<uint32_t>(prefixValidLifetime);
      cursor->writeBE<uint32_t>(prefixPreferredLifetime);
      cursor->writeBE<uint32_t>(0); // reserved
      cursor->push(prefix.first.bytes(), IPAddressV6::byteCount());
    }

    // MTU option
    cursor->writeBE<uint8_t>(5); // Option type (MTU)
    cursor->writeBE<uint8_t>(1); // Option length = 1 (x8)
    cursor->writeBE<uint16_t>(0); // Reserved
    cursor->writeBE<uint32_t>(mtu);
  };

  auto bodyLength = getAdvertisementPacketBodySize(prefixes.size());

  IPAddressV6 srcIP(IPAddressV6::LINK_LOCAL, intf->getMac());
  IPv6Hdr ipv6(srcIP, dstIP);
  ipv6.trafficClass = 0xe0; // CS7 precedence (network control)
  ipv6.payloadLength = ICMPHdr::SIZE + bodyLength;
  ipv6.nextHeader = IP_PROTO_IPV6_ICMP;
  ipv6.hopLimit = 255;

  ICMPHdr icmp6(ICMPV6_TYPE_NDP_ROUTER_ADVERTISEMENT, 0, 0);

  icmp6.serializeFullPacket(cursor, dstMac, intf->getMac(), intf->getVlanID(),
                            ipv6, bodyLength, serializeBody);
}
Exemplo n.º 2
0
Packet Entry::getSample(void){
	IP srcIP(srcMask[0], srcMask[1], srcMask[2], srcMask[3]);
	IP dstIP(dstMask[0], dstMask[1], dstMask[2], dstMask[3]);
	Packet pkt(srcIP, dstIP, srcPort, dstPort, protocol);
	return pkt;
}