?? tables.c
字號:
if (rt->rt_state & RTS_INTERNAL) { /* * Check if the subnetmask is shorter than the (class-based) * netmask. This test works because equal values are not * possible for these routes (RTS_SUBNET is always set). */ if ( (rt->rt_ifp->int_subnetmask | rt->rt_ifp->int_netmask) == rt->rt_ifp->int_subnetmask) { /* Longer mask. Replace with class-based value. */ pNsin->sin_addr.s_addr = htonl (rt->rt_ifp->int_netmask); } } } } ripRouteToAddrs (rt, &pDsin, &pGsin, &pNsin); pIfp = rt->rt_ifp; if (((state & RTS_OTHER) == 0) && (pIfp) && (pIfp->leakHook)) { if (pIfp->leakHook (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr) == OK) { free ((char *)rt); return ((struct rt_entry *)NULL); } } ripInsque ((NODE *)rt, (NODE *)rh); if (routedDebug > 1) logMsg ("Adding route to %x through %x (mask %x).\n", pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, 0, 0, 0); if ((rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL | RTS_OTHER)) == 0 && (ret = ripSystemRouteAdd (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, flags)) == ERROR) { if (errno != EEXIST && gate->sa_family < AF_MAX) { if (routedDebug) logMsg ("Error %x adding route to %s through gateway %s.\n", errno, (int)(*afswitch[dst->sa_family].af_format) (dst), (int)(*afswitch[gate->sa_family].af_format) (gate), 0, 0, 0); } if (routedDebug) logMsg ("Error %x adding new route.\n", errno, 0, 0, 0, 0, 0); if (errno == ENETUNREACH) { ripRemque ((NODE *)rt); free ((char *)rt); rt = 0; } } else { /* Store copy of metric in kernel routing table for IP group MIB. */ if (ret == OK) { rt->inKernel = TRUE; ripRouteMetricSet (rt); } ripState.ripGlobal.rip2GlobalRouteChanges++; } return ((struct rt_entry *)rt); }STATUS rtchange ( struct rt_entry *rt, struct sockaddr *gate, short metric, struct sockaddr *netmask, int tag, int from, struct interface *ifp ) { int add = 0, delete = 0, newgateway = 0; struct rt_entry oldroute; struct sockaddr_in *pDsin; struct sockaddr_in *pGsin; struct sockaddr_in *pNsin; char address[32]; int flags; BOOL wasInterfaceRoute = FALSE; FIXLEN (gate); FIXLEN (&(rt->rt_router)); FIXLEN (&(rt->rt_dst)); if (!equal (&rt->rt_router, gate)) { newgateway++; if (routedDebug > 1) logMsg ("Changing route gateway.\n", 0, 0, 0, 0, 0, 0); } else if (metric != rt->rt_metric) if (routedDebug > 1) logMsg ("Changing route metric.\n", 0, 0, 0, 0, 0, 0); if (tag != rt->rt_tag) if (routedDebug > 1) logMsg ("Changing route tag.\n", 0, 0, 0, 0, 0, 0); if ((rt->rt_state & RTS_INTERNAL) == 0) { /* * If changing to different router, we need to add * new route and delete old one if in the kernel. * If the router is the same, we need to delete * the route if has become unreachable, or re-add * it if it had been unreachable. */ if (newgateway) { add++; if ((rt->rt_metric != HOPCNT_INFINITY) || rt->inKernel) delete++; } else if (metric == HOPCNT_INFINITY) delete++; else if (rt->rt_metric == HOPCNT_INFINITY) add++; } /* * If routedInput() had set the metric to HOPCNT_INFINITY + 1 to * trick us into adding a route with orignal metric of 15 (adjusted to 16 * to accommodate the additional hop), reset the metric to * HOPCNT_INFINITY */ if (metric > HOPCNT_INFINITY) metric = HOPCNT_INFINITY; if (delete) oldroute = *rt; /* Record the route flags ignoring the UP flag */ flags = rt->rt_flags & ~RTF_UP; if ((rt->rt_state & RTS_INTERFACE) && delete) { wasInterfaceRoute = TRUE; rt->rt_state &= ~RTS_INTERFACE; rt->rt_flags |= RTF_GATEWAY; if (metric > rt->rt_metric && delete) if (routedDebug) logMsg ("Warning! %s route to interface %s (timed out).\n", (int)(add ? "Changing" : "Deleting"), (int)(rt->rt_ifp ? rt->rt_ifp->int_name : "?"), 0, 0, 0, 0); } if (add) { rt->rt_router = *gate; if (ifp) rt->rt_ifp = ifp; else { rt->rt_ifp = ripIfWithDstAddr (&rt->rt_router, NULL); if (rt->rt_ifp == 0) rt->rt_ifp = ripIfWithNet (&rt->rt_router); } if (netmask != (struct sockaddr *)NULL) { rt->rt_netmask = *netmask; } else { /* * Leave the netmask value as zero if a default route is used. * The rt_ifp field is zero in that case, so no other value * is available. */ bzero ((char *)&rt->rt_netmask, sizeof (rt->rt_netmask)); rt->rt_netmask.sa_family = AF_INET; rt->rt_netmask.sa_len = 16; pNsin = (struct sockaddr_in *)&rt->rt_netmask; if ( ((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr) pNsin->sin_addr.s_addr = htonl (rt->rt_ifp->int_subnetmask); } } rt->rt_metric = metric; rt->rt_tag = tag; if (from != 0) rt->rt_orgrouter = from; rt->rt_state |= RTS_CHANGED; if (newgateway) if (routedDebug > 1) logMsg ("Changing route gateway.\n", 0, 0, 0, 0, 0, 0); if (delete && !add) { ripRouteToAddrs (&oldroute, &pDsin, &pGsin, &pNsin); inet_ntoa_b (pDsin->sin_addr, (char *)&address); if (ripSystemRouteDelete (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, flags) == ERROR) { if (routedDebug) logMsg ("Route change - error %x removing old route.\n", errno, 0, 0, 0, 0, 0); } else { rt->inKernel = FALSE; ripState.ripGlobal.rip2GlobalRouteChanges++; } } else if (!delete && add) { ripRouteToAddrs (rt, &pDsin, &pGsin, &pNsin); if (ripSystemRouteAdd (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, flags) == ERROR) { if (routedDebug) logMsg ("Route change - error %x adding new route.\n", errno, 0, 0, 0, 0, 0); } else { /* Store metric in kernel routing table for IP group MIB. */ rt->inKernel = TRUE; ripRouteMetricSet (rt); ripState.ripGlobal.rip2GlobalRouteChanges++; } } else if (delete && add) { ripRouteToAddrs (&oldroute, &pDsin, &pGsin, &pNsin); inet_ntoa_b (pDsin->sin_addr, (char *)&address); if (ripSystemRouteDelete (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, flags) == ERROR) { if (routedDebug) logMsg ("Route change - error %x replacing old route.\n", errno, 0, 0, 0, 0, 0); } else { /* * If it was an interface route, now we are changing it to a * gateway route. Update the flags to reflect that */ if (wasInterfaceRoute) flags |= RTF_GATEWAY; ripRouteToAddrs (rt, &pDsin, &pGsin, &pNsin); if (ripSystemRouteAdd (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, flags) == ERROR) { if (routedDebug) logMsg ("Route change - error %x creating new route.\n", errno, 0, 0, 0, 0, 0); rt->inKernel = FALSE; } else { /* Store metric in kernel routing table for IP group MIB. */ rt->inKernel = TRUE; ripRouteMetricSet (rt); ripState.ripGlobal.rip2GlobalRouteChanges++; } } } else { /* Neither delete nor add - must be a metric change */ ripRouteMetricSet (rt); } return (OK); }STATUS rtdelete (rt) struct rt_entry *rt; { char address[32]; struct sockaddr_in *pDsin; struct sockaddr_in *pGsin; struct sockaddr_in *pNsin; if (routedDebug > 1) logMsg ("Removing route entry.\n", 0, 0, 0, 0, 0, 0); FIXLEN (&(rt->rt_router)); FIXLEN (&(rt->rt_dst)); if (rt->rt_metric < HOPCNT_INFINITY || rt->inKernel) { if ( (rt->rt_state & (RTS_INTERFACE|RTS_INTERNAL)) == RTS_INTERFACE) { if (routedDebug) logMsg ("Deleting route to interface %s? (timed out?).\n", (int)rt->rt_ifp->int_name, 0, 0, 0, 0, 0); } if ( (rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL | RTS_OTHER)) == 0) { ripRouteToAddrs (rt, &pDsin, &pGsin, &pNsin); inet_ntoa_b (pDsin->sin_addr, (char *)&address); if (ripSystemRouteDelete (pDsin->sin_addr.s_addr, pGsin->sin_addr.s_addr, pNsin->sin_addr.s_addr, rt->rt_flags & ~RTF_UP) == ERROR) { if (routedDebug) logMsg ("Route delete - error %x removing route.\n", errno, 0, 0, 0, 0, 0); } else { rt->inKernel = FALSE; ripState.ripGlobal.rip2GlobalRouteChanges++; } } } ripRemque ((NODE *)rt); /* * If this is an interface route and there exists reference to it, * then that means that there are other interfaces that have * addresses that match this route. We need to add new routes for * those interfaces. * if rt_refcnt == rt_subnets_cnt, it means that all the interfaces * are subnetted, ie 164.10.1.1/24, 164.10.2.2/24, etc * if rt_refcnt != rt_subnets_cnt, it means that atleast one * interface is not subnetted, e.g 164.10.1.1/16, 164.10.2.2/24, etc */ if (rt->rt_state & RTS_INTERFACE && rt->rt_refcnt && ! (rt->rt_state & RTS_EXTERNAL)) { if (rt->rt_refcnt != rt->rt_subnets_cnt) { /* * We are deleting a non-subnetted interface route and there * exist other non-subnetted interfaces on the same network. * We need to add a route for the network through one of those * interfaces */ ifRouteAdd (&(rt->rt_dst), rt->rt_refcnt - 1, rt->rt_subnets_cnt, FALSE, rt->rt_ifp->int_subnetmask); } else { /* * We are deleting an "internal" route that we had generated * for border gateway filtering. There exist other interfaces * that need this route. We need to add another route through * one of those interfaces */ ifRouteAdd (&(rt->rt_dst), rt->rt_refcnt - 1,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -