/* 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); }
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; }