📄 port.cc
字号:
rip_packet_bytes, entries_ptr, n_entries, src_address, new_peer) == false) { why = c_format("packet failed authentication (%s): %s", af_state().auth_handler()->effective_name(), af_state().auth_handler()->error().c_str()); record_bad_auth_packet(why, src_address, src_port, p); return; } if (n_entries == 0) { // No entries in packet, nothing further to do. return; }#elif defined (INSTANTIATE_IPV6) const uint8_t* entries_ptr = rip_packet + RipPacketHeader::size(); uint32_t n_entries = (rip_packet_bytes - RipPacketHeader::size()) / PacketRouteEntry<A>::size(); size_t calc_bytes = n_entries * PacketRouteEntry<A>::size() + RipPacketHeader::size(); if (calc_bytes != rip_packet_bytes) { why = c_format("Packet did not contain an integral number of route " "entries"); record_bad_packet(why, src_address, src_port, p); }#endif if (src_port == RIP_AF_CONSTANTS<A>::IP_PORT && rph.command() == RipPacketHeader::RESPONSE) { record_response_packet(p); parse_response(src_address, src_port, entries_ptr, n_entries); } else { XLOG_ASSERT(rph.command() == RipPacketHeader::REQUEST); if (src_port == RIP_AF_CONSTANTS<A>::IP_PORT) { record_request_packet(p); } else { counters().incr_non_rip_requests_recv(); } parse_request(src_address, src_port, entries_ptr, n_entries); }}// ----------------------------------------------------------------------------// Port<IPv4> Specialized methods//#ifdef INSTANTIATE_IPV4template <>voidPort<IPv4>::parse_response(const Addr& src_addr, uint16_t src_port, const uint8_t* entries_ptr, uint32_t n_entries){ static IPv4 net_filter("255.0.0.0"); static IPv4 class_b_net("128.0.0.0"); static IPv4 class_c_net("192.0.0.0"); static IPv4 class_d_net("224.0.0.0"); static IPv4 class_e_net("240.0.0.0"); string why; Peer<Addr>* p = peer(src_addr); if (p == 0) { p = create_peer(src_addr); p->counters().incr_packets_recv(); p->counters().incr_update_packets_recv(); } for (uint32_t i = 0; i < n_entries; i++) { const uint8_t* pre_ptr = entries_ptr + i * PacketRouteEntry<IPv4>::size(); const PacketRouteEntry<IPv4> pre(pre_ptr); if (pre.addr_family() != AF_INET) { why = c_format("Bad address family (%u instead of %u)", pre.addr_family(), AF_INET); record_bad_route(why, src_addr, src_port, p); continue; } uint16_t metric = pre.metric(); if (metric > RIP_INFINITY) { why = c_format("Bad metric (%u > %u)", metric, RIP_INFINITY); record_bad_route(why, src_addr, src_port, p); continue; } uint32_t prefix_len = pre.prefix_len(); if (prefix_len > Addr::ADDR_BITLEN) { why = c_format("Bad prefix length (%u > %u)", prefix_len, Addr::ADDR_BITLEN); record_bad_packet(why, src_addr, src_port, p); continue; } IPv4Net net = pre.net(); IPv4 addr = pre.addr(); if (prefix_len == 0 && addr != IPv4::ZERO()) { // Subnet mask not specified, thus apply a clasfull mask if (addr < class_b_net) { prefix_len = 8; // Class A } else if (addr < class_c_net) { prefix_len = 16; // Class B } else if (addr < class_d_net) { prefix_len = 24; // Class C } else { prefix_len = 32; // XXX check RFC! } net = IPv4Net(IPv4(addr), prefix_len); } if (net == RIP_AF_CONSTANTS<Addr>::DEFAULT_ROUTE() && accept_default_route() == false) { continue; } IPv4 masked_net = net.masked_addr() & net_filter; if (masked_net.is_multicast()) { why = c_format("Multicast route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net.is_loopback()) { why = c_format("Loopback route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net >= class_e_net) { why = c_format("Experimental route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net == IPv4::ZERO()) { if (net.prefix_len() != 0) { why = c_format("Net 0"); record_bad_route(why, src_addr, src_port, p); continue; } else if (accept_default_route() == false) { why = c_format("Default route"); record_bad_route(why, src_addr, src_port, p); continue; } } if (prefix_len == Addr::ADDR_BITLEN) { // // Check if the route is for one of my own addresses or // for a directly connected broadcast address. // bool my_addr_found = false; bool bcast_addr_found = false; const IfMgrIfTree& iftree = _pm.iftree(); IfMgrIfTree::IfMap::const_iterator if_iter; for (if_iter = iftree.interfaces().begin(); if_iter != iftree.interfaces().end(); ++if_iter) { const IfMgrIfAtom& iface = if_iter->second; // Test if interface is enabled and the link state is up if ((! iface.enabled()) || iface.no_carrier()) continue; IfMgrIfAtom::VifMap::const_iterator vif_iter; for (vif_iter = iface.vifs().begin(); vif_iter != iface.vifs().end(); ++vif_iter) { const IfMgrVifAtom& vif = vif_iter->second; // Test if vif is enabled if (! vif.enabled()) continue; // // Test if there is a matching interface address // or a broadcast address. // IfMgrVifAtom::IPv4Map::const_iterator a4_iter; for (a4_iter = vif.ipv4addrs().begin(); a4_iter != vif.ipv4addrs().end(); ++a4_iter) { const IfMgrIPv4Atom& a4 = a4_iter->second; if (! a4.enabled()) continue; // Test if my own address if (a4.addr() == net.masked_addr()) { my_addr_found = true; break; } // Test if the broadcast address if (a4.has_broadcast() && (a4.broadcast_addr() == net.masked_addr())) { bcast_addr_found = true; break; } } } } if (my_addr_found) { why = c_format("My interface address (%s)", net.masked_addr().str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (bcast_addr_found) { why = c_format("My broadcast address (%s)", net.masked_addr().str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } } IPv4 nh = pre.nexthop(); if (nh == IPv4::ZERO()) { nh = src_addr; } else if (nh == _pio->address()) { // Nexthop points to us, ignore route (either poison-rev or bogus) continue; } else { // Test if nh is on the receiving subnet const IfMgrIfTree& iftree = _pm.iftree(); const IfMgrIPv4Atom* ifa = iftree.find_addr(_pio->ifname(), _pio->vifname(), _pio->address()); if (IPv4Net(nh, ifa->prefix_len()) != IPv4Net(ifa->addr(), ifa->prefix_len())) { nh = src_addr; } } metric += cost(); if (metric > RIP_INFINITY) { metric = RIP_INFINITY; } // // XXX review // Want to do anything with tag? // uint16_t tag = pre.tag(); p->update_route(net, nh, metric, tag, PolicyTags()); }}#endif // INSTANTIATE_IPV4// ----------------------------------------------------------------------------// Port<IPv6> Specialized methods//#ifdef INSTANTIATE_IPV6template <>voidPort<IPv6>::parse_response(const Addr& src_addr, uint16_t src_port, const uint8_t* entries_ptr, uint32_t n_entries){ string why; Peer<Addr>* p = peer(src_addr); if (p == 0) { p = create_peer(src_addr); p->counters().incr_packets_recv(); p->counters().incr_update_packets_recv(); } // ALL_ONES is used as a magic value to indicate no nexthop has been set. IPv6 nh = IPv6::ALL_ONES(); for (uint32_t i = 0; i < n_entries; i++) { const uint8_t* pre_ptr = entries_ptr + i * PacketRouteEntry<IPv6>::size(); const PacketRouteEntry<IPv6> pre(pre_ptr); if (pre.is_nexthop()) { nh = pre.nexthop(); if (! nh.is_linklocal_unicast()) nh = IPv6::ZERO(); if (nh == IPv6::ZERO()) { nh = src_addr; } continue; } else if (nh == IPv6::ALL_ONES()) { why = c_format("Route specified before nexthop"); record_bad_route(why, src_addr, src_port, p); continue; } uint16_t metric = pre.metric(); if (metric > RIP_INFINITY) { why = c_format("Bad metric (%u > %u)", metric, RIP_INFINITY); record_bad_route(why, src_addr, src_port, p); continue; } if (pre.prefix_len() > Addr::ADDR_BITLEN) { why = c_format("Bad prefix length (%u > %u)", pre.prefix_len(), Addr::ADDR_BITLEN); record_bad_packet(why, src_addr, src_port, p); continue; } IPv6Net net = pre.net(); IPv6 masked_net = net.masked_addr(); if (masked_net.is_multicast()) { why = c_format("Multicast route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net.is_linklocal_unicast()) { why = c_format("Linklocal route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net.is_loopback()) { why = c_format("Loopback route (%s)", masked_net.str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } if (masked_net == IPv6::ZERO()) { if (net.prefix_len() != 0) { why = c_format("Net 0"); record_bad_route(why, src_addr, src_port, p); continue; } else if (accept_default_route() == false) { why = c_format("Default route"); record_bad_route(why, src_addr, src_port, p); continue; } } if (pre.prefix_len() == Addr::ADDR_BITLEN) { // // Check if the route is for one of my own addresses. // bool my_addr_found = false; const IfMgrIfTree& iftree = _pm.iftree(); IfMgrIfTree::IfMap::const_iterator if_iter; for (if_iter = iftree.interfaces().begin(); if_iter != iftree.interfaces().end(); ++if_iter) { const IfMgrIfAtom& iface = if_iter->second; // Test if interface is enabled and the link state is up if ((! iface.enabled()) || iface.no_carrier()) continue; IfMgrIfAtom::VifMap::const_iterator vif_iter; for (vif_iter = iface.vifs().begin(); vif_iter != iface.vifs().end(); ++vif_iter) { const IfMgrVifAtom& vif = vif_iter->second; // Test if vif is enabled if (! vif.enabled()) continue; // // Test if there is a matching interface address // or a broadcast address. // IfMgrVifAtom::IPv6Map::const_iterator a6_iter; for (a6_iter = vif.ipv6addrs().begin(); a6_iter != vif.ipv6addrs().end(); ++a6_iter) { const IfMgrIPv6Atom& a6 = a6_iter->second; if (! a6.enabled()) continue; // Test if my own address if (a6.addr() == net.masked_addr()) { my_addr_found = true; break; } } } } if (my_addr_found) { why = c_format("My interface address (%s)", net.masked_addr().str().c_str()); record_bad_route(why, src_addr, src_port, p); continue; } } metric += metric + cost(); if (metric > RIP_INFINITY) { metric = RIP_INFINITY; } // // XXX review // Want to do anything with tag? // uint16_t tag = pre.tag(); p->update_route(net, nh, metric, tag, PolicyTags()); }}#endif // INSTANTIATE_IPV6// ----------------------------------------------------------------------------// Instantiations#ifdef INSTANTIATE_IPV4template class Port<IPv4>;#endif#ifdef INSTANTIATE_IPV6template class Port<IPv6>;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -