⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 port.cc

📁 RIP 协议实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
							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 + -