📄 rtab.c
字号:
rp->rt_child[LESS]->rt_parent = rp; /* <--- we added this */
if( dn->rt_rip2 )
NU_Deallocate_Memory(dn->rt_rip2);
if( dn->rt_auth )
NU_Deallocate_Memory(dn->rt_auth);
dn->rt_device = 0;
dn->rt_parent = 0;
dn->rt_refcnt = 0;
dn->rt_use = 0;
dn->rt_flags = 0;
UTL_Zero(&(dn->rt_gateway), sizeof(SCK_SOCKADDR_IP));
if( q == 0 )
{
Root_Node = rp;
Root_Node->rt_parent = 0;
}
else
{
if(dn == q->rt_child[LESS])
q->rt_child[LESS] = rp;
else
q->rt_child[MORE] = rp;
rp->rt_parent = q;
}
}
else
{
/* only one child is attached to node */
q = dn->rt_parent;
rp = dn;
/* save off the node that exists. */
if( dn->rt_child[LESS] )
s = dn->rt_child[LESS];
else
s = dn->rt_child[MORE];
if( dn->rt_rip2 )
NU_Deallocate_Memory(dn->rt_rip2);
if( dn->rt_auth )
NU_Deallocate_Memory(dn->rt_auth);
dn->rt_device = 0;
dn->rt_parent = 0;
dn->rt_refcnt = 0;
dn->rt_use = 0;
dn->rt_flags = 0;
UTL_Zero(&(dn->rt_gateway), sizeof(SCK_SOCKADDR_IP));
/* If the dn is the top node, then reset Root_Node */
if( q == 0 )
{
Root_Node = s;
Root_Node->rt_parent = 0;
}
else
{
/* find which child of the parent is the deleted node */
if( rp == q->rt_child[LESS] )
q->rt_child[LESS] = s;
else
q->rt_child[MORE] = s;
s->rt_parent = q;
}
}
NU_Deallocate_Memory(dn);
return(0);
} /* RTAB_Delete_Node */
/*************************************************************************
*
* FUNCTION
*
* NU_Get_Default_Route
*
* DESCRIPTION
*
* Get the default route for the NU_Rip2 system.
*
* Note: Caller must allocate memory for the rt_rip2, rt_auth and
* rt_device structures within the default_route they passed
* in to this function.
*
* INPUTS
*
* None.
*
* OUTPUTS
*
* *ROUTE_NODE
*
*************************************************************************/
ROUTE_NODE *RTAB_Get_Default_Route(VOID)
{
return RTAB_Default_Route;
} /* NU_Get_Default_Route */
/*************************************************************************
*
* FUNCTION
*
* RTAB_Redirect
*
* DESCRIPTION
*
* Process an ICMP redirect.
*
* INPUTS
*
* dst
* gateway
* flags
* src
*
* OUTPUTS
*
* None.
*
*************************************************************************/
VOID RTAB_Redirect(UINT32 dst, UINT32 gateway, INT flags, UINT32 src)
{
ROUTE_NODE *rt, *rtg;
SCK_SOCKADDR_IP ip_dest;
SCK_SOCKADDR_IP gw;
DV_DEVICE_ENTRY *temp_dev;
if (!IP_Localaddr(gateway))
return;
ip_dest.sck_family = SK_FAM_IP;
ip_dest.sck_len = sizeof (ip_dest);
ip_dest.sck_addr = dst;
/* Find a route to the original IP address that caused the redirect. */
if ( (rt = RTAB_Find_Route(&ip_dest)) == NU_NULL)
return;
/* Verify the gateway is directly reachable. A route will be returned if
the gateway is on this network. */
gw.sck_addr = gateway;
if ((rtg = RTAB_Find_Route(&gw)) == 0)
return;
/* Validate the redirect. There are several conditions that must be
checked.
- The RTE_DONE flag must not be set.
- The IP address of the router that sent the redirect must equal the
current rt_gateway for the destination.
- The interface for the new gateway must equal the current interface for
the destination, i.e., the new gateway must be on the same network as
the current gateway.
*/
if ( (flags & RT_DONE) || (src != rt->rt_gateway.sck_addr) ||
(rt->rt_device != rtg->rt_device) )
{
RTAB_Free(rt);
return;
}
/* Now make sure that the redirect was not to ourself. That is that the new
gateway does not match one of our addresses. */
for(temp_dev = DEV_Table.dv_head;
temp_dev != NU_NULL;
temp_dev = temp_dev->dev_next)
{
/* Is there an exact match on the IP address. */
if (temp_dev->dev_addr.dev_ip_addr == gateway)
break;
/* Is this a broadcast for our network. */
if (temp_dev->dev_addr.dev_net == gateway)
break;
}
/* If an interface was found with a matching IP address then this is not a
valid redirect. */
if (temp_dev)
{
RTAB_Free(rt);
return;
}
/* If the old route is to a gateway. */
if (rt->rt_flags & RT_GATEWAY)
{
/* If the current route is a network route (HOST flag not set) and the
redirect is for a host, then create a new route.
*/
if ( ((rt->rt_flags & RT_HOST) == 0) && (flags & RT_HOST) )
{
/* Create the new route. */
RTAB_Add_Route( rt->rt_device, dst, 0xffffffffUL, gateway,
(INT16)(flags | RT_GATEWAY | RT_DYNAMIC) );
}
else
{
/* Modify the existing route. */
rt->rt_flags |= RT_MODIFIED;
rt->rt_gateway.sck_addr = gateway;
*(UINT32 *)rt->rt_rip2->nexthop = gateway;
}
}
/* If a route was located, free it. */
if (rt)
RTAB_Free(rt);
} /* RTAB_Redirect */
/*************************************************************************
*
* FUNCTION
*
* RTAB_Delete_Route
*
* DESCRIPTION
*
* Removes a route from the routing table.
*
* INPUTS
*
* *ip_dest The route you want to delete
*
* OUTPUTS
*
* STATUS NU_SUCCESS if the route was deleted
* NU_INVALID_ADDRESS if the route was
* not found.
* NU_INVALID_PARM if a pointer parameter
* is NU_NULL.
*
*************************************************************************/
STATUS RTAB_Delete_Route (UINT8 *ip_dest)
{
STATUS ret_status;
ROUTE_NODE *rt;
SCK_SOCKADDR_IP route_ip_num;
#if (INCLUDE_SNMP == NU_TRUE)
UINT8 gateway[IP_ADDR_LEN];
#endif
/* Verify pointer parameter is non-null. */
if (ip_dest)
{
/* Store the IP address in this socket structure. This will be used
below to remove the route associated with this IP address. */
route_ip_num.sck_addr = IP_ADDR (ip_dest);
/* Find the node that contains this route and remove it. Note that the
route_ip_num structure only has the IP address filled in. The
RTAB_Find_Route function only uses the IP address. */
rt = RTAB_Find_Route(&route_ip_num);
/* Make sure a route was found. */
if (rt)
{
/* Remove the route from the MIB2 information. */
#if (INCLUDE_SNMP == NU_TRUE)
PUT32(gateway, 0, rt->rt_gateway.sck_addr);
/*
There are two cases. They are for the type of route. Either a
direct or indirect. If the next hop is a gateway then the route
type is indirect. A type of 4 is indirect and 3 is direct. Also
8 is for the routing protocol type. In this case it is RIP.
*/
if (rt->rt_flags & RT_GATEWAY)
/* Remove this route from the SNMP routing table */
SNMP_ipRouteTableUpdate (SNMP_DELETE, (INT)(rt->rt_device->dev_index),
rt->rt_rip2->ip_addr,
rt->rt_rip2->metric, (UNSIGNED)-1,
(UNSIGNED)-1, (UNSIGNED)-1, (UNSIGNED)-1,
gateway, 4, 8, 0,
rt->rt_rip2->submask, "0.0");
else
/* Remove this route from the SNMP routing table */
SNMP_ipRouteTableUpdate (SNMP_DELETE, (INT)(rt->rt_device->dev_index),
rt->rt_rip2->ip_addr,
rt->rt_rip2->metric, (UNSIGNED)-1,
(UNSIGNED)-1, (UNSIGNED)-1, (UNSIGNED)-1,
gateway, 4, 8, 0,
rt->rt_rip2->submask, "0.0");
#endif
/* The reference count was incremented by RTAB_Find_Route.
We are not using the route so decrement the reference count. */
rt->rt_refcnt--;
/* Delete the route. */
ret_status = RTAB_Delete_Node (rt);
}
else
ret_status = NU_INVALID_ADDRESS;
}
else
ret_status = NU_INVALID_PARM;
return (ret_status);
} /* end RTAB_Delete_Route */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -